本文档记录 sentence-transformers/multi-qa-MiniLM-L6-cos-v1 多语言问答句嵌入模型在昇腾 NPU(Ascend 910B3)上的迁移适配、精度评测与性能验证结果。
该模型基于 MiniLM-L6(6 层 Transformer,384 维隐藏层),通过 Mean Pooling + L2 归一化将文本编码为 384 维语义向量。与 all-MiniLM-L6-v2 同架构,但专门针对问答(QA)检索场景微调:在大量 (question, answer) 对上使用对比学习训练,使语义匹配的 QA 对在向量空间中更接近。特别适合 FAQ 检索、客服问答匹配等场景。
相关获取地址:
sentence-transformers/multi-qa-MiniLM-L6-cos-v1| 组件 | 版本 |
|---|---|
torch | 2.8.0 |
torch_npu | 2.8.0.post4 |
transformers | 5.8.1 |
sentence-transformers | 5.5.0 |
CANN | 8.5.1 |
8 × Ascend 910B3conda create -n sentence-transformers_multi-qa-MiniLM-L6-cos-v1 python=3.11 -y
conda activate sentence-transformers_multi-qa-MiniLM-L6-cos-v1
pip install torch==2.8.0 torch_npu==2.8.0.post4 \
-i https://pypi.tuna.tsinghua.edu.cn/simple
pip install transformers sentence-transformers numpy \
-i https://pypi.tuna.tsinghua.edu.cn/simplepython inference.py --text "How many people live in Berlin?" --device npu
python inference.py --batch_file questions.txt --device npu编程接口:
from inference import MultiQAMiniLMEncoder
encoder = MultiQAMiniLMEncoder(
model_path="./sentence-transformers_multi-qa-MiniLM-L6-cos-v1", device="npu"
)
embeddings = encoder.encode(["How many people live in Berlin?"])
# embeddings.shape → (1, 384)python inference.py --text "How many people live in Berlin?" --device npu预期输出:384 维归一化嵌入向量,无运行时错误。
测试条件:23 条多样化测试句子,batch_size=32,NPU 预热 1 轮。
| 指标 | 数值 |
|---|---|
| NPU 吞吐量 | 1,381.1 sentences/s |
MiniLM-L6 仅 6 层 384 维,推理速度极快(1381 sent/s),是所有 BERT 类模型中最快的之一。
分别在 CPU 和 NPU 上对 23 条多样化测试句子推理,比较 384 维嵌入向量的余弦相似度和语义相似度矩阵的 Pearson 相关系数。
| 指标 | 数值 |
|---|---|
| 精度误差率 | 0.0000% |
结论:精度误差率 0.0000%,NPU 与 CPU 输出完全一致,评测通过。
AutoModel.from_pretrained() 加载,model.to("npu:0") 迁移(embeddings * mask).sum(1) / mask.sum(1)import torch, torch_npu
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("multi-qa-MiniLM-L6-cos-v1").to("npu:0")
tokenizer = AutoTokenizer.from_pretrained("multi-qa-MiniLM-L6-cos-v1")
text = "How many people live in Berlin?"
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
inputs = {k: v.to("npu:0") for k, v in inputs.items()}
with torch.no_grad():
outputs = model(**inputs)
mask = inputs["attention_mask"].unsqueeze(-1).float()
embedding = (outputs.last_hidden_state * mask).sum(1) / mask.sum(1)
embedding = torch.nn.functional.normalize(embedding, p=2, dim=1)