时间: 2026-02-27 模式: research+实测
在 RS1000(AMD EPYC 9634,84核,AVX-512+BF16)上测试 Qwen3-Embedding-0.6B 各优化方案
Baseline: 吞吐量 15.7条/秒,RSS 1972MB,P95延迟 784ms,中位延迟 59ms
已有报告 leb-cpu-embedding-acceleration.md 针对 Intel Xeon E3-1270 v6(AVX2,无AVX-512),
本任务硬件为 AMD EPYC 9634(AVX-512+BF16),需要独立调研测试。
| threads | 吞吐量(条/秒) | RSS(MB) | 耗时(s) |
|---|---|---|---|
| 4 | 12.6 | 2005 | 15.8 |
| 8 | 12.5 | 2103 | 16.0 |
| 16 | 12.1 | 2062 | 16.6 |
| 32 | 11.3 | 2153 | 17.8 |
| 48 | 10.6 | 2262 | 19.0 |
| 64 | 10.0 | 3052 | 19.9 |
| 84 | 9.4 | 3060 | 21.3 |
关键发现:线程越多越慢! threads=4 最优(12.6条/秒),threads=84 最差(9.4条/秒)。
原因:84核 EPYC 分 2 NUMA node,大量线程导致跨 NUMA 内存访问 + cache 竞争。
| batch_size | 吞吐量(条/秒) | RSS(MB) | 耗时(s) |
|---|---|---|---|
| 8 | 17.3 | 3050 | 11.6 |
| 16 | 15.9 | 3050 | 12.6 |
| 32 | 13.4 | 3051 | 15.0 |
| 64 | 9.1 | 3051 | 21.9 |
| 128 | 5.6 | 3051 | 35.7 |
| 256 | 3.5 | 2534 | 57.2 |
最优:batch_size=8,17.3条/秒(比 Baseline 15.7 提升 10.2%)
批次越小反而越快,说明模型在 CPU 上受限于计算而非 IO,小 batch 减少内存复制。
测试条件:threads=4,batch=8,500条语料(sentence_transformers)
| 精度 | 吞吐量(条/秒) | RSS(MB) | 加速比 |
|---|---|---|---|
| FP32 | 18.3 | 1945 | 1.00x |
| BF16 | 18.3 | 2986 | 1.00x |
结论:BF16 对吞吐量无提升,内存反增 ~1GB。
原因:sentence_transformers 内部已做 FP32 cast,BF16 权重在推理时被提升回 FP32,硬件 BF16 加速未生效。
向量一致性:FP32 vs BF16 余弦 mean=1.0000,min=0.9936(质量无损)。
结论:fastembed 0.7.4 不支持 Qwen3-Embedding,跳过。
⚠️ 注意:optimum 导出的 model.onnx 仅 2MB(异常,正常应为 ~1.2GB),
说明只导出了 embedding 层而非完整 transformer 模型,ONNX 推理结果不可信。
| 方案 | 吞吐量(条/秒) | RSS(MB) | 备注 |
|---|---|---|---|
| ONNX FP32 | 6.0 | 2272 | 模型导出异常(仅2MB),结果无效 |
| ONNX INT8 | 13.3 | 2852 | 同上,结果无效 |
需要重新用正确方式导出完整 ONNX 模型后再测。
ONNX 模型:optimum 导出,model.onnx(1.5MB) + model.onnx_data(2273MB),输出:token_embeddings + sentence_embedding
| 方案 | 吞吐量(条/秒) | RSS(MB) | vs Baseline |
|---|---|---|---|
| ONNX FP32 | 5.9 | 2754 | -62% |
| ONNX INT8 | 13.3 | 3442 | -15% |
结论:ONNX 路径在 RS1000 上比 sentence_transformers 慢。
ONNX FP32 仅 5.9条/秒(sentence_transformers FP32 18.3条/秒),差距 3x。
ONNX INT8 13.3条/秒,仍低于 Baseline 15.7条/秒。
原因:ONNX Runtime 1.24.2 在 AMD EPYC 上未充分利用 AVX-512,sentence_transformers 通过 PyTorch 2.10 的 AVX-512 优化路径更高效。
RS1000 实际只有 1 个 NUMA node(4核可见),非预期的 84核双 NUMA 架构。
说明 RS1000 是虚拟机/容器,仅分配了 4 个 vCPU,这解释了为何 threads=4 最优。
最优组合:threads=4,batch_size=8,FP32,sentence_transformers
| 指标 | Baseline | 最优组合 | 变化 |
|---|---|---|---|
| 吞吐量 | 15.7 条/秒 | ~17-18 条/秒 | +10~15% |
| RSS 内存 | 1972 MB | ~2000 MB | 持平 |
| batch_size | 32 | 8 | 降低 |
| threads | 4 | 4 | 不变 |
batch_size=8,threads=4,FP32,sentence_transformers
- 吞吐量提升约 10%(15.7 → 17.3 条/秒)
- 内存持平,无额外依赖,一行参数修改
| 方案 | 原因 |
|---|---|
| 增加线程数 | RS1000 实为 4 vCPU 虚拟机,多线程反而慢 |
| BF16 精度 | 无吞吐提升,内存多用 1GB |
| ONNX FP32 | 5.9条/秒,比 baseline 慢 62% |
| ONNX INT8 | 13.3条/秒,仍低于 baseline,且内存更大 |
| fastembed | 不支持 Qwen3-Embedding |
model.encode(texts, batch_size=8, show_progress_bar=False)
# threads 保持默认 4,不需要额外设置
(报告由爱衣补全,Ai.Res session 因 process poll 卡死未能完成通知)