文本对相似度(CLIP)
更新时间:2026-09-14
简介
文本对相似度算子,两段文本各过 CLIP 文本塔后取余弦相似度。算子只产出分数,不按 min/max 过滤,过滤交给 pipeline 的 where。CLIP 封装复用 daft/aihc/functions/multimodal/_clip_dual_tower.py。
功能描述
- 复用
ClipDualTower(transformersCLIPModel/CLIPProcessor):两侧文本各编码一次,向量做 L2 归一化后点积即余弦,取值 [-1, 1],输出保留 6 位小数 - 两列按行配对,长度不一致直接抛
ValueError - 只对两侧都非空的行推理;任一侧为空、纯空白或非字符串留 None
- 按
batch_size微批推理;某批异常时该批整批留 None(记 exception 日志),其余批不受影响 - 文本编码按 CLIP 文本塔上限截断(
truncation=True, max_length=77) aihc_udf的num_gpus > 0且 CUDA 可用时按cuda:{rank % 卡数}选卡,否则跑 CPU;CPU 上 float16 由封装层自动回落 float32dtype非法抛ValueError,权重目录不存在抛FileNotFoundError,都发生在初始化阶段
算子参数
输入
| 输入 | 含义 |
|---|---|
| texts_a | 文本 A 列 |
| texts_b | 文本 B 列,与 A 按行配对 |
输出
| 输出 | 含义 |
|---|---|
| sim | float64,两段文本 CLIP 文本向量的余弦相似度;任一侧为空或该批推理失败返回 None |
参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| model_path | str | "/opt/aihc/model" | 权重根目录 |
| model_name | str | "openai/clip-vit-base-patch32" | 相对 model_path 的 CLIP 权重子目录 |
| dtype | str | "float32" | 权重精度,可选 float16 / float32 / bfloat16 |
| batch_size | int | 32 | 算子内部推理的微批大小,与 aihc_udf 的 batch_size 相互独立 |
| rank | int | 0 | 多卡场景 worker 序号,实际设备取 cuda:{rank % 卡数} |
注意事项
- CLIP 文本塔有 77 token 上限,超长文本的尾部不参与计算。长文档比对建议先切分,或改用「文本 Embedding 相似度」算子。
- CLIP 是图文对比学习出来的模型,不是文本检索模型,分数区间与专用文本 embedding 模型(BGE、Qwen3-Embedding 等)不同,阈值不能互相套用。
- 权重需包含
CLIPModel与CLIPProcessor的完整文件:ClipDualTower加载整个 CLIP(含图像塔),即使本算子只用文本塔。
调用示例
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_pair_similarity import TextPairSimilarity
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
18ds = daft.from_pydict(
19 {
20 "a": ["a dog on grass", "a dog on grass", "a dog on grass"],
21 "b": ["a dog on grass", "quantum physics lecture notes", ""],
22 }
23 )
24 ds = ds.with_column(
25 "sim",
26 aihc_udf(
27 TextPairSimilarity,
28 construct_args={
29 "model_path": "/path/to/models",
30 "model_name": "openai/clip-vit-base-patch32",
31 },
32 num_cpus=1,
33 num_gpus=1,
34 concurrency=1,
35 batch_size=32,
36 )(col("a"), col("b")),
37 )
38 ds.show()
评价此篇文章
