文本 Embedding 相似度
更新时间:2026-09-14
简介
文本与参照集的平均 embedding 余弦相似度算子:把每条文本编码成向量,与一组参照文本的向量逐个算余弦后取均值,用来衡量样本与「目标风格 / 目标任务」参照集的接近程度。只产出分数,min_score / max_score 一类阈值过滤交给 pipeline 的 where。
功能描述
- 只走本地模型(
AutoTokenizer+AutoModel),算子内不联网,不调用任何在线 embedding 接口 - 三种 pooling:
None取最后一个 token 的 hidden state(默认)、"mean"均值、"weighted_mean"按位置加权均值;left padding 时按attention_mask取真实末位 - 参照集两种形态,必须二选一:
valid_texts传原文(在__init__里现场编码),或valid_embeddings_path指向预先算好的.npy/.npz(.npz取embeddings键,路径支持本地 / BOS / S3 / HTTP)。都不给或都给抛ValueError - 预计算向量会校验形状为
(n, dim)且n>0、dim等于模型hidden_size,不符抛ValueError;随后做 L2 归一化(零向量的模按 1 处理) n_shot只取参照集前 n 条input_template是单占位符模板(默认"{text}"),对参照集与待测文本同样套用,可用来加 Qwen3-Embedding 推荐的 instruct 前缀max_length是分词截断长度,默认 4096- 批量编码,与逐条编码数值一致:mean / weighted_mean 只差一个正标量,pooling 后紧跟 L2 normalize 把标量约掉;last-token pooling 用
attention_mask取真实末位下标,与 batch 无关 - 待测文本与参照集向量都已归一化,点积即余弦,对参照集取均值即输出分数
- 空文本 / 非字符串留 None;整批编码失败时自动退回逐条编码,避免一条坏数据带走整批;非有限值(nan / inf)写 None
- CPU 上非 float32 会告警并强制回落 float32;GPU 上每次 transform 结束调用
empty_cache - 只接收单列文本,多字段拼接由上游完成
算子参数
输入
| 输入 | 含义 |
|---|---|
| texts | 文本字符串数组 |
输出
| 输出 | 含义 |
|---|---|
| score | float64,与参照集各向量余弦的均值;文本为空或编码失败返回 None |
参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| model_path | str | "/opt/aihc/model" | 权重根目录 |
| model_name | str | "Qwen/Qwen3-Embedding-0.6B" | 相对 model_path 的 embedding 模型目录;也可换 BAAI/bge-m3 等 |
| pooling | str 或 None | None | 取向量的方式:None 取最后一个 token(默认)、"mean"、"weighted_mean";其它值抛 ValueError |
| valid_texts | list[str] 或 None | None | 参照集原文,适合几十条以内 |
| valid_embeddings_path | str 或 None | None | 预先算好的参照集向量文件,.npy(二维数组)或 .npz(取 embeddings 键),可为 BOS 路径 |
| n_shot | int 或 None | None | 只取参照集前 n 条;None 表示全用 |
| input_template | str | "{text}" | 单占位符模板,按 template.format(text=<行内容>) 套用 |
| max_length | int | 4096 | 分词截断长度 |
| batch_size | int | 16 | 编码批大小,与 aihc_udf 的 batch_size 相互独立 |
| dtype | str | "float32" | 模型精度:float32 / float16 / bfloat16 |
| trust_remote_code | bool | True | 透传给 transformers |
| rank | int | 0 | 多卡场景 worker 序号,实际设备取 cuda:{rank % 卡数} |
注意事项
valid_texts形态下参照集会在每个 UDF actor 冷启时各编码一遍,参照集上千条时改用valid_embeddings_path。- 预计算向量必须由同一个模型、同一种 pooling 算出。算子只校验维度,pooling 或模型换了但维度恰好相同时不会报错,只会算出错的分数。
- 分数是「与给定参照集的平均余弦」,参照集不同则分数不可比,阈值需跟参照集一起固定。
- 与「文本对相似度(CLIP)」的分数量纲不可比:一个是 CLIP 图文对齐空间的两两余弦,一个是文本 embedding 模型对参照集的均值。
- 算子不联网下载权重,权重缺失时在初始化阶段直接抛
FileNotFoundError。
调用示例
Python
1from __future__ import annotations
2
3import os
4
5import daft
6from daft import col
7
8from daft.aihc.common.udf import aihc_udf
9from daft.aihc.functions.text.text_embd_similarity import TextEmbdSimilarity
10
11if __name__ == "__main__":
12 if os.getenv("DAFT_RUNNER", "native") == "ray":
13 import ray
14 ray.init(dashboard_host="0.0.0.0", ignore_reinit_error=True)
15 daft.set_runner_ray()
16 daft.set_execution_config(actor_udf_ready_timeout=6000, min_cpu_per_task=0)
17
18samples = {
19 "text": [
20 "There is a lovely cat.",
21 "It is challenging to train a large language model.",
22 None,
23 ]
24 }
25 ds = daft.from_pydict(samples)
26 ds = ds.with_column(
27 "score",
28 aihc_udf(
29 TextEmbdSimilarity,
30 construct_args={
31 "model_path": "/path/to/models",
32 "model_name": "Qwen/Qwen3-Embedding-0.6B",
33 # 参照集形态 1:直接传原文
34 "valid_texts": ["There is a cute cat.", "The cat there is lovely."],
35 # 参照集形态 2(大参照集推荐,与形态 1 二选一):
36 # "valid_embeddings_path": "bos://your-bucket/ref/text_embd_valid.npy",
37 },
38 num_cpus=1,
39 num_gpus=1,
40 concurrency=1,
41 batch_size=16,
42 )(col("text")),
43 )
44 ds.show()
评价此篇文章
