Name Last Update
..
backends Loading commit data...
README.md Loading commit data...
__init__.py Loading commit data...
cache.py Loading commit data...
client.py Loading commit data...
languages.py Loading commit data...
logging_utils.py Loading commit data...
nllb_flores_short_map.py Loading commit data...
prompts.py Loading commit data...
protocols.py Loading commit data...
scenes.py Loading commit data...
service.py Loading commit data...
settings.py Loading commit data...
text_splitter.py Loading commit data...

README.md

Translation Module

translation/ 是当前项目翻译能力的主目录。
如果要开发、部署、联调、压测翻译服务,优先看这份文档。

对应服务:

相关脚本与报告:

1. 设计目标

翻译模块采用:

  • 一个 translator service
  • 多个 capability backend
  • 一个统一外部接口:model + scene

这套设计的目标是:

  • 翻译能力可以独立扩展、独立启停
  • scene、语言码、prompt 模板、模型方向约束等翻译域知识集中在 translation/
  • 配置尽量集中在 <code>config/config.yaml</code>services.translation
  • 配置错误应尽早报错,不做静默兼容和隐式回退

2. 目录结构

核心文件:

后端实现:

3. 配置约定

翻译的部署配置统一放在:

示例:

services:
  translation:
    service_url: "http://127.0.0.1:6006"
    default_model: "llm"
    default_scene: "general"
    timeout_sec: 10.0
    cache:
      ttl_seconds: 62208000
      sliding_expiration: true
    capabilities:
      qwen-mt:
        enabled: true
        backend: "qwen_mt"
        model: "qwen-mt-flash"
        base_url: "https://dashscope-us.aliyuncs.com/compatible-mode/v1"
        timeout_sec: 10.0
        use_cache: true
      llm:
        enabled: true
        backend: "llm"
        model: "qwen-flash"
        base_url: "https://dashscope-us.aliyuncs.com/compatible-mode/v1"
        timeout_sec: 30.0
        use_cache: true
      deepl:
        enabled: false
        backend: "deepl"
        api_url: "https://api.deepl.com/v2/translate"
        timeout_sec: 10.0
        use_cache: true
      nllb-200-distilled-600m:
        enabled: true
        backend: "local_nllb"
        model_id: "facebook/nllb-200-distilled-600M"
        model_dir: "./models/translation/facebook/nllb-200-distilled-600M"
        ct2_model_dir: "./models/translation/facebook/nllb-200-distilled-600M/ctranslate2-float16"
        ct2_compute_type: "float16"
        ct2_conversion_quantization: "float16"
        ct2_auto_convert: true
        ct2_inter_threads: 4
        ct2_max_queued_batches: 32
        ct2_batch_type: "examples"
        ct2_decoding_length_mode: "source"
        ct2_decoding_length_extra: 8
        ct2_decoding_length_min: 32
        device: "cuda"
        torch_dtype: "float16"
        batch_size: 16
        max_input_length: 256
        max_new_tokens: 64
        num_beams: 1
        use_cache: true
      opus-mt-zh-en:
        enabled: true
        backend: "local_marian"
        model_id: "Helsinki-NLP/opus-mt-zh-en"
        model_dir: "./models/translation/Helsinki-NLP/opus-mt-zh-en"
        ct2_model_dir: "./models/translation/Helsinki-NLP/opus-mt-zh-en/ctranslate2-float16"
        ct2_compute_type: "float16"
        ct2_conversion_quantization: "float16"
        ct2_auto_convert: true
        device: "cuda"
        torch_dtype: "float16"
        batch_size: 16
        max_input_length: 256
        max_new_tokens: 256
        num_beams: 1
        use_cache: true
      opus-mt-en-zh:
        enabled: true
        backend: "local_marian"
        model_id: "Helsinki-NLP/opus-mt-en-zh"
        model_dir: "./models/translation/Helsinki-NLP/opus-mt-en-zh"
        ct2_model_dir: "./models/translation/Helsinki-NLP/opus-mt-en-zh/ctranslate2-float16"
        ct2_compute_type: "float16"
        ct2_conversion_quantization: "float16"
        ct2_auto_convert: true
        device: "cuda"
        torch_dtype: "float16"
        batch_size: 16
        max_input_length: 256
        max_new_tokens: 256
        num_beams: 1
        use_cache: true

配置边界:

  • config.yaml 只放部署和运行参数 例如 service_urldefault_modeldefault_sceneenabledbase_urlapi_urlmodel_dirdevice
  • translation 目录内部放翻译静态知识 例如 scene 规则、语言码映射、prompt 模板、Marian 方向约束

说明:

  • service_urldefault_modeldefault_scene 只从 YAML 读取
  • 不再通过环境变量静默覆盖翻译行为配置
  • 密钥仍通过环境变量提供
  • local_nllb / local_marian 当前由 CTranslate2 运行;首次启动时若 ct2_model_dir 不存在,会从 model_dir 自动转换

4. 环境变量

当前翻译模块主要依赖:

# Qwen / LLM
DASHSCOPE_API_KEY=sk-xxx

# DeepL
DEEPL_AUTH_KEY=xxx

服务启动端口仍可以由启动脚本环境控制:

TRANSLATION_HOST=0.0.0.0
TRANSLATION_PORT=6006

5. Scene 规则

当前只支持 3 个标准 scene:

  • general
  • sku_name
  • ecommerce_search_query

定义位置:

约定:

  • scene 是公共接口字段
  • 不再接受旧的 context
  • 不再对外暴露 prompt
  • LLM prompt 在服务内根据 scene 自动生成

6. 对外 HTTP 接口

服务入口在:

默认地址:

  • http://localhost:6006

提供接口:

  • POST /translate
  • GET /health

6.1 POST /translate

请求体:

{
  "text": "商品名称",
  "target_lang": "en",
  "source_lang": "zh",
  "model": "opus-mt-zh-en",
  "scene": "sku_name"
}

字段说明:

  • text 支持 stringstring[]
  • target_lang 目标语言
  • source_lang 源语言
  • model 已配置的 capability 名称
  • scene 翻译场景

响应体:

{
  "text": "商品名称",
  "target_lang": "en",
  "source_lang": "zh",
  "translated_text": "Product name",
  "status": "success",
  "model": "opus-mt-zh-en",
  "scene": "sku_name"
}

批量时:

  • 返回列表和输入等长
  • 单条失败返回 null

6.2 GET /health

返回示例:

{
 "status": "healthy",
  "service": "translation",
  "default_model": "llm",
  "default_scene": "general",
  "available_models": ["qwen-mt", "llm", "nllb-200-distilled-600m", "opus-mt-zh-en", "opus-mt-en-zh"],
  "enabled_capabilities": ["qwen-mt", "llm", "nllb-200-distilled-600m", "opus-mt-zh-en", "opus-mt-en-zh"],
  "loaded_models": ["qwen-mt", "llm", "nllb-200-distilled-600m", "opus-mt-zh-en", "opus-mt-en-zh"]
}

说明:

  • translator service 进程启动时会一次性初始化全部已启用 capability
  • 因此本地模型加载失败、依赖缺失、配置错误会在启动阶段直接暴露,而不是拖到首个在线请求

7. 代码调用方式

业务侧统一这样调用:

from translation.client import create_translation_client

translator = create_translation_client()
result = translator.translate(
    text="商品名称",
    source_lang="zh",
    target_lang="en",
    model="opus-mt-zh-en",
    scene="sku_name",
)

批量调用:

results = translator.translate(
    text=["商品1", "商品2"],
    source_lang="zh",
    target_lang="en",
    model="opus-mt-zh-en",
    scene="sku_name",
)

接口 shape 约定:

  • translate(text="...") 返回 Optional[str]
  • translate(text=[...]) 返回 List[Optional[str]]
  • 批量模式始终保持“等长、同序返回”;某条失败时对应位置为 None
  • backend/client 可通过 supports_batch 暴露是否支持原生批量;服务端会在必要时自动逐条拆分并保持返回 shape 不变

8. 具体实现说明

8.1 Qwen-MT

实现文件:

特点:

  • 云端机翻
  • 支持 Redis 翻译缓存
  • 适合质量优先、非超高并发场景

注意:

  • 当前默认 qwen-mt-flash 限速较低
  • 大量重复请求应依赖缓存

8.2 LLM Translation

实现文件:

特点:

  • 通用大模型翻译
  • 根据 scene 生成内部 prompt
  • 更灵活,但成本和稳定性取决于上游模型
  • 支持 Redis 翻译缓存

8.3 DeepL

实现文件:

特点:

  • 商业翻译 API
  • scene 会映射到内部上下文
  • 当前默认关闭
  • 支持 Redis 翻译缓存

8.4 facebook/nllb-200-distilled-600M

实现文件:

模型信息:

  • Hugging Face 名称:facebook/nllb-200-distilled-600M
  • 简介:多语种翻译:覆盖约 200 种语言。作为NLLB-200系列的蒸馏版本,该模型通过知识蒸馏技术将原130亿参数模型压缩至600M,同时保持了80%以上的翻译质量。
  • 本地目录:models/translation/facebook/nllb-200-distilled-600M
  • 当前磁盘占用:约 2.4G
  • 支持 Redis 翻译缓存
  • 模型类型:多语种 Seq2Seq 机器翻译模型
  • 来源:Meta NLLB(No Language Left Behind)系列的 600M 蒸馏版
  • 结构特点:
    • Transformer encoder-decoder 架构
    • 12 层 encoder + 12 层 decoder
    • d_model=1024
    • 通过 source_lang + forced_bos_token_id 控制翻译方向
    • 语言标识采用 language_script 形式,例如 eng_Latnzho_Hans
    • 改良 encoder-decoder(含嵌入层缩放 scale_embedding、相对位置等)

核心配置如下:

配置项 参数值 备注
隐藏层维度(d_model 1024
编码器 / 解码器层数 12 / 12
注意力头数 16
FFN 维度 4096
词表大小 256,206 多语统一词表
最大序列长度 1024 tokens 满足长文本翻译

config.json 片段(示意):

{
  "d_model": 1024,
  "encoder_layers": 12,
  "decoder_layers": 12,
  "attention_dropout": 0.1,
  "use_cache": true,
  "torch_dtype": "float32",
  "max_length": 200
}

模型定位:

  • 优势是多语覆盖面广,一个模型可以支撑很多语言方向
  • 劣势是相较于 Marian 这种双语专用模型,推理更重、延迟更高
  • 更适合做索引翻译(离线 / 批量),不建议作为在线 query 翻译的默认方案

显存占用情况:

  • 600M 模型半精度(float16)权重约 ~1.25G;推理还会叠加 CUDA context、allocator reserve、激活张量、batch、输入/生成长度等开销
  • 当前这台 Tesla T4 上,优化后的实际运行峰值大约在 2.8-3.0 GiB

当前实现特点:

  • backend 类型:local_nllb
  • 运行时:CTranslate2 Translator
  • 支持多语
  • 调用时必须显式传 source_lang
  • 语言码映射定义在 <code>translation/languages.py</code>
  • 当前 T4 推荐配置:device=cudact2_compute_type=float16ct2_inter_threads=4ct2_max_queued_batches=32ct2_batch_type=examplesct2_decoding_length_mode=source(+8,min=32)batch_size=16max_new_tokens=64

当前实现已经利用的优化:

  • 已做批量分块:translate() 会按 capability 的 batch_size 分批进入模型
  • 已切换到 CTranslate2 推理引擎:不再依赖 PyTorch generate()
  • 已设置方向控制:NLLB 通过 target prefix 指定目标语言
  • 已启用半精度:当前配置为 float16
  • 已关闭高开销搜索:默认 num_beams=1,更接近线上低延迟设置

和你给出的批处理示例对照:

  • 核心思路已经覆盖,现有实现与 tokenizer(batch) -> model.generate(...) -> batch_decode(...) 一致
  • 差异在于服务端额外做了语言校验、统一 chunking、输入长度约束和单条/批量 shape 保持
  • “预计算 attention mask” 目前没有单独缓存层;现状是每个 batch 在 tokenizer 阶段实时生成 attention_mask,这也是 HF 常规推理路径

优化空间(按场景):

  • 线上 query:优先补测 batch_size=1 的真实延迟与 tail latency,而不是继续拉大 batch。
  • 离线批量:可再尝试更激进的 batching / 长度分桶 / 独立批处理队列(吞吐更高,但会增加在线尾延迟风险)。
  • 进一步降显存 / 提速:可在当前 CT2 方案上继续评估 int8_float16

8.5 opus-mt-zh-en

实现文件:

模型信息:

  • Hugging Face 名称:Helsinki-NLP/opus-mt-zh-en
  • 本地目录:models/translation/Helsinki-NLP/opus-mt-zh-en
  • 当前磁盘占用:约 1.2G
  • 模型类型:Marian / OPUS MT 专用双语翻译模型
  • 方向约束:只支持 zh -> en

结构特点:

  • encoder-decoder Seq2Seq
  • 聚焦特定语言对
  • 模型更小、加载更轻、吞吐更高
  • 支持 Redis 翻译缓存

8.6 opus-mt-en-zh

实现文件:

模型信息:

  • Hugging Face 名称:Helsinki-NLP/opus-mt-en-zh
  • 本地目录:models/translation/Helsinki-NLP/opus-mt-en-zh
  • 当前磁盘占用:约 1.5G
  • 模型类型:Marian / OPUS MT 专用双语翻译模型
  • 方向约束:只支持 en -> zh

结构特点:

  • encoder-decoder Seq2Seq
  • 双语定向模型
  • 更适合中英双向拆分部署
  • 支持 Redis 翻译缓存

8.7 翻译缓存

  • 所有 translation capability 都使用统一的 Redis 缓存层
  • 每个 capability 通过各自的 use_cache 控制是否启用缓存
  • 缓存 key 格式固定为 trans:{model}:{target_lang}:{source_text[:4]}{sha256}

9. 本地模型安装与部署

9.1 准备环境

cd /data/saas-search
./scripts/setup_translator_venv.sh

9.2 下载模型

下载全部本地模型:

./.venv-translator/bin/python scripts/translation/download_translation_models.py --all-local

下载完成后,默认目录应存在:

models/translation/facebook/nllb-200-distilled-600M
models/translation/Helsinki-NLP/opus-mt-zh-en
models/translation/Helsinki-NLP/opus-mt-en-zh

9.3 打开能力

编辑 <code>config/config.yaml</code>,把对应模型的 enabled 改成 true

9.4 启动服务

./scripts/start_translator.sh

建议:

  • 本地模型服务使用单 worker
  • 避免多 worker 重复加载模型
  • GPU 机器上优先使用 cuda + float16
  • CPU 只建议用于功能验证或离线低频任务
  • 对 NLLB,T4 上优先采用 batch_size=16 + max_new_tokens=64 + ct2_compute_type=float16 + ct2_inter_threads=4 + ct2_max_queued_batches=32 + ct2_batch_type=examples + ct2_decoding_length_mode=source(+8,min=32)

9.5 验证

健康检查:

curl http://127.0.0.1:6006/health

翻译测试:

curl -X POST http://127.0.0.1:6006/translate \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "男士偏光飞行员太阳镜",
    "source_lang": "zh",
    "target_lang": "en",
    "model": "opus-mt-zh-en",
    "scene": "sku_name"
  }'

10. 性能测试与复现

说明:

  • 本节现有数值是 2026-03-18 的 Hugging Face / PyTorch 基线结果。
  • 切换到 CTranslate2 后需要重新跑一轮基准,尤其关注 nllb-200-distilled-600m 的单条延迟、并发 tail latency 和 opus-mt-* 的 batch throughput。

性能脚本:

数据集:

最新报告:

10.1 先看哪组数据

这里把 3 类结果分开看,不再混在一张表里:

  • batch_sweep 固定 concurrency=1,只比较不同 batch_size 的单流批处理性能
  • concurrency_sweep 固定 batch_size=1,看“单条请求”在不同并发下的延迟和吞吐
  • batch x concurrency matrix 同时看 batch_sizeconcurrency 的交互效应;本轮限制为 batch_size * concurrency <= 128

建议:

  • 看线上 query 翻译延迟:优先看 concurrency_sweep
  • 看离线批量翻译吞吐:优先看 batch_sweep
  • 看单 worker 服务容量边界:再看 batch x concurrency matrix

10.2 本轮补测参数

测试时间:2026-03-18

环境:

  • GPU:Tesla T4 16GB
  • Python env:.venv-translator
  • Torch / Transformers:2.10.0+cu128 / 5.3.0

统一参数:

  • cache:关闭(--disable-cache),避免缓存命中干扰性能结果
  • batch_sweep:每档 256 items
  • concurrency_sweep:固定 batch_size=1,每档 32 requests
  • batch x concurrency matrix:每档 32 requests,且只保留 batch_size * concurrency <= 128
  • 预热:1 batch

复现命令:

cd /data/saas-search
./.venv-translator/bin/python benchmarks/translation/benchmark_translation_local_models.py

本轮扩展压测复现命令:

cd /data/saas-search
./.venv-translator/bin/python benchmarks/translation/benchmark_translation_local_models.py \
  --suite extended \
  --disable-cache \
  --serial-items-per-case 256 \
  --concurrency-requests-per-case 32 \
  --concurrency-batch-size 1 \
  --output-dir perf_reports/20260318/translation_local_models

单模型扩展压测示例:

./.venv-translator/bin/python benchmarks/translation/benchmark_translation_local_models.py \
  --single \
  --suite extended \
  --model opus-mt-zh-en \
  --source-lang zh \
  --target-lang en \
  --column title_cn \
  --scene sku_name \
  --disable-cache \
  --batch-size-list 1,4,8,16,32,64 \
  --concurrency-list 1,2,4,8,16,64 \
  --serial-items-per-case 256 \
  --concurrency-requests-per-case 32 \
  --concurrency-batch-size 1

单条请求延迟复现:

./.venv-translator/bin/python benchmarks/translation/benchmark_translation_local_models.py \
  --single \
  --suite extended \
  --model nllb-200-distilled-600m \
  --source-lang zh \
  --target-lang en \
  --column title_cn \
  --scene sku_name \
  --disable-cache \
  --batch-size-list 1 \
  --concurrency-list 1,2,4,8,16,64 \
  --serial-items-per-case 256 \
  --concurrency-requests-per-case 32 \
  --concurrency-batch-size 1

10.3 单流 batch 结果

这组只看 concurrency=1,不要把这里的 request p95 当作线上并发请求的 p95。

nllb-200-distilled-600m zh -> en

Batch Items/s Avg item ms Req p95 ms
1 2.91 343.488 616.27
4 8.44 118.545 722.95
8 14.85 67.335 728.47
16 27.28 36.662 769.18
32 38.6 25.908 1369.88
64 58.3 17.152 1659.9

nllb-200-distilled-600m en -> zh

Batch Items/s Avg item ms Req p95 ms
1 1.91 524.917 866.33
4 4.94 202.473 1599.74
8 8.25 121.188 1632.29
16 13.52 73.956 1649.65
32 21.27 47.017 1827.16
64 32.64 30.641 2031.25

opus-mt-zh-en zh -> en

Batch Items/s Avg item ms Req p95 ms
1 6.15 162.536 274.74
4 15.34 65.192 356.0
8 25.51 39.202 379.84
16 41.44 24.129 797.93
32 54.36 18.397 1693.31
64 70.15 14.255 2161.59

opus-mt-en-zh en -> zh

Batch Items/s Avg item ms Req p95 ms
1 4.53 220.598 411.57
4 10.12 98.844 761.49
8 14.63 68.361 1930.85
16 24.33 41.1 2098.54
32 33.91 29.487 2152.28
64 42.47 23.547 2371.85

批处理结论:

  • 纯吞吐看,4 个方向的最佳 raw throughput 都出现在 batch_size=64
  • 如果还要兼顾单个 batch 的尾延迟,batch_size=16 往往更均衡
  • opus-mt-zh-en 是本轮 bulk 场景最快模型,nllb en->zh 最慢

10.4 单条请求并发结果

这组固定 batch_size=1,可以直接理解成“单条请求在不同并发下的表现”。

nllb-200-distilled-600m zh -> en

Concurrency Items/s Avg req ms Req p50 ms Req p95 ms
1 4.17 239.99 226.34 373.27
2 4.1 477.99 459.36 703.96
4 4.1 910.74 884.71 1227.01
8 4.04 1697.73 1818.48 2383.8
16 4.07 2801.91 3473.63 4145.92
64 4.04 3714.49 3610.08 7337.3

nllb-200-distilled-600m en -> zh

Concurrency Items/s Avg req ms Req p50 ms Req p95 ms
1 2.16 463.18 439.54 670.78
2 2.15 920.48 908.27 1213.3
4 2.16 1759.87 1771.58 2158.04
8 2.15 3284.44 3658.45 3971.01
16 2.14 5669.15 7117.7 7522.48
64 2.14 7631.14 7510.97 14139.03

opus-mt-zh-en zh -> en

Concurrency Items/s Avg req ms Req p50 ms Req p95 ms
1 9.21 108.53 91.7 179.12
2 8.92 219.19 212.29 305.34
4 9.09 411.76 420.08 583.97
8 8.85 784.14 835.73 1043.06
16 9.01 1278.4 1483.34 1994.56
64 8.82 1687.08 1563.48 3381.58

opus-mt-en-zh en -> zh

Concurrency Items/s Avg req ms Req p50 ms Req p95 ms
1 3.6 277.73 145.85 1180.37
2 3.55 559.38 346.71 1916.96
4 3.53 997.71 721.04 2944.17
8 3.51 1644.28 1590.93 3632.99
16 3.5 2600.18 2586.34 5554.04
64 3.52 3366.52 2780.0 7950.41

并发结论:

  • 当前本地 seq2seq backend 内部是单模型锁,单 worker 下提高客户端并发基本不会提升吞吐,主要会把等待时间堆到请求延迟上
  • 线上 query 翻译如果追求稳定延迟,应优先控制在低并发;8+ 并发后,4 个方向的 p95 都明显恶化
  • 在线场景里,opus-mt-zh-en 延迟最稳;nllb en->zh 最慢,且并发放大后尾延迟最明显

10.5 batch x concurrency 怎么看

完整矩阵见:

这张表主要回答两个问题:

  • 如果已经知道自己要跑离线批处理,batch_size 拉大后,在不同并发下吞吐会不会继续涨
  • 如果要拿单 worker 服务扛请求,在哪个 batch_size x concurrency 组合下开始明显排队

本轮矩阵的共同特征:

  • 吞吐主要由 batch_size 决定,concurrency 不是主要增益来源
  • batch_size 固定时,concurrency1 升到 2/4/8/...items/s 变化很小,但 avg req ms / p95 会持续抬升
  • 因此当前实现更像“单 worker + 内部串行 GPU 推理服务”,不是一个靠客户端并发放大吞吐的服务

NLLB 性能优化经验:

  • 起作用的优化点 1:float16 + cuda
    • 当前本地 NLLB 由 CTranslate2cuda:0float16 运行
    • 优化后在 T4 上的峰值显存约 2.8-3.0 GiB
  • 起作用的优化点 2:batch_size=16
    • 相比 batch_size=8,吞吐提升明显
    • 继续提升到 32 虽然还能增吞吐,但 batch p95 和 batch max 会恶化很多
  • 起作用的优化点 3:ct2_inter_threads=4 + ct2_max_queued_batches=32
    • batch=1 高并发商品标题场景收益最直接
    • 相比默认 CT2 配置,zh->enen->zh 的在线吞吐都能稳定提升
  • 起作用的优化点 4:动态解码上限
    • 推荐 ct2_decoding_length_mode=source
    • 推荐 ct2_decoding_length_extra=8
    • 推荐 ct2_decoding_length_min=32
    • 这样可以保留 max_new_tokens=64 的安全上限,同时让短标题不再为长标题上限付费
  • 起作用的优化点 5:ct2_batch_type=examples
    • 在当前数据和 T4 上,比 tokens 更稳
    • 更适合作为线上默认
  • 不建议直接作为默认的实验:
    • max_new_tokens=48
    • 大 batch 和在线吞吐都会继续变好
    • 但商品标题 spot-check 已看到明显截断,尤其 en->zh
  • 收益有限或不稳定的实验:
    • ct2_batch_type=tokens
    • ct2_max_queued_batches16 再继续拉高,收益很小
    • ct2_decoding_length_mode=source(+4,min=24) 更快,但仍有少量长标题截断风险

为什么最终没有采用其它方案:

  • 当前本地最优路径已经切到 CTranslate2 + float16
  • 对这个 600M 级 encoder-decoder 模型,T4 上最有效的是把 CT2 的并行和解码策略调对
  • 因此这轮没有继续引入更重的服务化栈
  • 如果未来目标变成“继续压缩显存”或“进一步追求更低延迟”,再评估 int8_float16 或服务级微批处理队列会更合适

关键结论:

  • 当前机器上,opus-mt-zh-en 是三个新增本地模型里最快的
  • opus-mt-en-zh 大约是 opus-mt-zh-en 吞吐的一半
  • nllb-200-distilled-600M 在 T4 上推荐 cuda + CTranslate2 float16 + batch_size=16 + ct2_inter_threads=4 + ct2_max_queued_batches=32 + dynamic decoding
  • nllb 最终可用,但吞吐仍明显低于两个 Marian 模型,更适合多语覆盖或独立资源环境

最终推荐部署方案:

  • 模型:facebook/nllb-200-distilled-600M
  • 设备:cuda
  • 精度:float16
  • 推荐卡型:至少 Tesla T4 16GB 这一级别
  • 推荐 batch:16
  • 推荐 max_input_length256
  • 推荐 max_new_tokens64
  • 推荐 num_beams1
  • 推荐 CT2 并行:ct2_inter_threads=4
  • 推荐 CT2 队列:ct2_max_queued_batches=32
  • 推荐 CT2 batch 类型:examples
  • 推荐动态解码:ct2_decoding_length_mode=sourcect2_decoding_length_extra=8ct2_decoding_length_min=32
  • 运行方式:单 worker,避免重复加载

更详细的性能说明见:

11. 开发说明

如果要新增翻译 backend,最少需要做这些事:

  1. <code>translation/backends/</code> 下新增实现
  2. <code>translation/service.py</code> 注册 backend 创建逻辑
  3. <code>config/config.yaml</code>services.translation.capabilities 中新增 capability 配置
  4. 如果有新的静态规则:

原则:

  • 不要再引入 translation provider 兼容层
  • 不要把 scene / prompt / 语言方向规则重新散落到别的目录
  • 不要在代码里写隐式默认和静默兼容

12. 常见建议

  • 中英商品标题双向场景,优先考虑 opus-mt-zh-enopus-mt-en-zh
  • 多语种统一方案,可以考虑 nllb-200-distilled-600M
  • nllb 更适合独占资源环境
  • 如果追求更高质量或更复杂语义处理,可使用 qwen-mtllm
  • 如果追求稳定商业 API,可考虑 deepl

13. 相关文档