PickScore_v1 是 Yuval Kirstain 等在论文 Pick-a-Pic: An Open Dataset of User Preferences for Text-to-Image Generation 中提出的图文偏好打分模型。它以 OpenAI CLIP ViT-H/14 为骨干,在 Pick-a-Pic 大规模人工偏好数据集上微调,输入一条文本提示与若干候选图片,输出每张图片的偏好 logit 与归一化概率,用于 human-preference prediction、文生图模型评测、图像排序等任务。
本仓库基于官方权重(yuvalkirstain/PickScore_v1,权重为 fp32 全精度 safetensors,3.94 GB,912 个张量)在 昇腾 Ascend NPU 上完成部署适配,采用 vLLM-Ascend embedding 服务化 形态对外提供推理能力。
| 属性 | 值 |
|---|---|
| 架构 | CLIPModel(CLIP ViT-H/14 双塔) |
| 视觉塔 | hidden=1280 / heads=16 / layers=32 / patch=14 / 输入 224×224 |
| 文本塔 | hidden=1024 / heads=16 / layers=24 / max_len=77 / vocab=49408 |
| 投影维度 | 1024 |
| 权重 | model.safetensors(3,944,552,236 字节,912 张量,fp32) |
| 打分系数 | logit_scale=4.59375(训练终值,exp≈98.86) |
| 部署形态 | vLLM-Ascend 0.18.0 · embedding 任务 · OpenAI 兼容接口 |
PickScore_v1 的 config.json 声明 model_type=clip、architectures=["CLIPModel"]。在 vLLM 模型注册表中,CLIPModel 已映射到 CLIPEmbeddingModel(见 registry.py:"CLIPModel": ("clip", "CLIPEmbeddingModel")),即架构已存在,无需新增模型适配代码,本次工作属于「复用 + 服务化」策略:
clip.py 仅使用 nn.Conv2d(patch 嵌入)、nn.Linear、nn.LayerNorm、nn.Embedding、torch.cat 等原生 PyTorch 算子,未出现 Triton / CUDA-only 内核,昇腾算子门禁通过,无需降级或替换。--task 自动解析为 pooling 任务(runner=pooling),文本向量池化方式为 LAST(EOT token),与 CLIP 文本塔的池化语义一致。| 组件 | 版本 |
|---|---|
| 操作系统 | openEuler(Linux 5.10.0,aarch64) |
| 昇腾设备 | Ascend910 ×2(Atlas 800,HBM 64GB) |
| CANN | 8.5.1(npu-smi 25.5.5) |
| Python | 3.11.14 |
| PyTorch | 2.9.0 |
| torch_npu | 2.9.0.post1 |
| vLLM | 0.18.0 |
| vLLM-Ascend | 0.18.0 |
| transformers | 4.57.6 |
权重下载顺序:GitCode 镜像(ai.gitcode.com/hf_mirrors/yuvalkirstain/PickScore_v1)→ ModelScope → HuggingFace。本仓库实测通过 GitCode 镜像完成拉取,LFS 对象经 gitcode.com/hf_mirrors/.../info/lfs/objects/batch 签名 URL 直连 CDN 下载,sha256 校验通过。
pip install -r requirements.txtpython -m vllm.entrypoints.openai.api_server \
--model /path/to/PickScore_v1 \
--served-model-name PickScore_v1 \
--dtype float16 \
--max-model-len 77 \
--limit-mm-per-prompt '{"image": 1}' \
--max-num-seqs 8 \
--enforce-eager \
--gpu-memory-utilization 0.3 \
--port 8030 \
--trust-remote-code启动后暴露的接口:
GET /v1/models —— 就绪检查与模型信息POST /v1/embeddings —— 文本向量POST /v2/embed —— 图像/文本向量(Cohere 兼容,支持 images 字段)POST /pooling —— 通用向量化接口python inference.py --prompt "a warm orange sunset over the sea" \
--images sunset.png ocean.png服务启动后的最小验证:
# 1. 就绪检查
curl -sf http://127.0.0.1:8030/v1/models
# {"object":"list","data":[{"id":"PickScore_v1","object":"model",...}]}
# 2. 文本向量
curl -s -X POST http://127.0.0.1:8030/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"PickScore_v1","input":"a warm orange sunset","encoding_format":"float"}'
# 返回 data[0].embedding,维度 1024
# 3. 图像向量(base64 data-URI)
python inference.py --prompt "a calm deep blue ocean" --images ocean.png sunset.png实测一次典型打分:
prompt : a warm orange sunset over the sea
sunset.png logit= 19.7838 prob= 87.95%
ocean.png logit= 17.7964 prob= 12.05%
preferred image : sunset.png模型正确选择了与 prompt 语义匹配的图片。
在 Atlas 800(Ascend910,单卡)上对已部署服务的实测(n=20,热调用):
| 指标 | 文本向量 | 图像向量 |
|---|---|---|
| 平均延迟 | 27.0 ms | 16.5 ms |
| P50 延迟 | 26.8 ms | 16.5 ms |
| P95 延迟 | 27.9 ms | 16.7 ms |
| 吞吐 | 37.0 req/s | 60.6 req/s |
以 transformers CPU 推理(fp32)作为参考基线,对 vLLM-Ascend(fp16)输出做余弦相似度对比:
| 模态 | 服务端 vs CPU 参考余弦相似度 |
|---|---|
| 文本特征 | 0.999999 |
| 图像特征 | 0.999989 |
偏好打分一致性(两组 prompt×图片 交叉验证):
| prompt | sunset 概率 | ocean 概率 | 判定 |
|---|---|---|---|
| a warm orange sunset over the sea | 87.95% | 12.05% | 正确 |
| a calm deep blue ocean with gentle waves | 25.32% | 74.68% | 正确 |
差异主要来自 fp16 与 fp32 的舍入(约 ±1e-3 量级),不影响排序结论。
npu-smi info 确认空闲卡与端口;本仓库默认 8030,可 --port 调整。--limit-mm-per-prompt 使用 JSON 字符串格式 '{"image": 1}',旧版写法 image=1 会被拒绝。感谢 Yuval Kirstain 等作者开源 PickScore 与 Pick-a-Pic 数据集;本仓库的部署与验证基于昇腾 CANN / vLLM-Ascend 生态完成。