# 翻译模块 **快速上手**:见 `docs/QUICKSTART.md` 第 3.4 节。 ## 环境变量 ```bash # Qwen(默认) DASHSCOPE_API_KEY=sk-xxx # DeepL DEEPL_AUTH_KEY=xxx ``` > **重要限速说明(Qwen 机翻)** > 当前默认的 Qwen 翻译后端使用 `qwen-mt-flash` 云端模型,**官方限速较低,约 RPM=60(每分钟约 60 请求)**。 > - 推荐通过 Redis 翻译缓存复用结果,避免对相同文本重复打云端 > - 高并发场景需要在调用端做限流 / 去抖,或改为离线批量翻译 > - 如需更高吞吐,可考虑 DeepL 或自建翻译服务 ## 配置模型 翻译已改为“一个翻译服务 + 多种翻译能力”的结构: - 业务侧(`QueryParser` / indexer)统一调用 `http://127.0.0.1:6006` - 服务内按 `services.translation.capabilities` 加载并管理各翻译能力 - 已启用 capability 统一注册,后端实例按首次调用懒加载,避免多个本地模型在启动阶段一次性占满显存 - `config.yaml` 只保留部署相关配置;scene 规则、语言码映射、prompt 模板、模型方向约束等翻译域知识统一收口在 `translation/` 内部 - 每种能力独立配置 `enabled`、`model`、`base_url/api_url`、`timeout`、本地模型运行参数等部署项 - 每种能力显式声明 `backend` 类型,例如 `qwen_mt`、`llm`、`deepl`、`local_nllb`、`local_marian` - `service_url`、`default_model`、`default_scene` 只从 `config/config.yaml` 读取,不再接受环境变量静默覆盖 - 外部接口通过 `model + scene` 指定本次使用哪种能力、哪个场景 配置入口在 `config/config.yaml -> services.translation` ## 本地模型部署 本仓库已内置 3 个本地机翻 capability: - `nllb-200-distilled-600m` - `opus-mt-zh-en` - `opus-mt-en-zh` 推荐流程: 1. 创建独立运行环境:`./scripts/setup_translator_venv.sh` 2. 下载本地模型:`./.venv-translator/bin/python scripts/download_translation_models.py --all-local` 3. 在 `config/config.yaml` 中把对应 capability 的 `enabled` 改为 `true` 4. 启动服务:`./scripts/start_translator.sh` 默认模型目录: - `models/translation/facebook/nllb-200-distilled-600M` - `models/translation/Helsinki-NLP/opus-mt-zh-en` - `models/translation/Helsinki-NLP/opus-mt-en-zh` 说明: - 目前只支持 3 个标准 scene:`general`、`sku_name`、`ecommerce_search_query` - `nllb-200-distilled-600m` 支持多语,但依赖明确的 `source_lang` - 两个 OPUS 模型分别只支持 `zh -> en` 与 `en -> zh` - 本地模型建议单 worker 运行,避免重复加载占用显存 ## HTTP 接口契约(translator service,端口 6006) 服务默认监听 `http://localhost:6006`,提供: - `POST /translate`: 文本翻译(支持所有已启用 capability) - `GET /health`: 健康检查 ### `POST /translate` **请求体**: ```json { "text": "商品名称", "target_lang": "en", "source_lang": "zh", "model": "qwen-mt", "scene": "sku_name" } ``` - `text` 支持两种形式: - 单条:`string` - 批量:`string[]`(等长返回,顺序对应) **响应体**(单条): ```json { "text": "商品名称", "target_lang": "en", "source_lang": "zh", "translated_text": "Product name", "status": "success", "model": "qwen-mt", "scene": "sku_name" } ``` **响应体**(批量): ```json { "text": ["商品名称1", "商品名称2"], "target_lang": "en", "source_lang": "zh", "translated_text": ["Product name 1", null], "status": "success", "model": "qwen-mt", "scene": "sku_name" } ``` 批量模式下,**单条失败用 `null` 占位**(即 `translated_text[i] = null`),保证长度与顺序一一对应,避免部分失败导致整批报错。 说明: - `scene` 是标准字段 - `prompt` 不属于外部接口;LLM prompt 由 translator service 内部根据 `scene` 生成 - `model` 只能选择已在 `services.translation.capabilities` 中启用的能力 - `/health` 会返回 `default_model`、`default_scene`、`enabled_capabilities` 与 `loaded_models` --- ## 开发者接口约定(代码调用) 代码侧(如 query/indexer)通过 `translation.create_translation_client()` 获取实例并调用 `translate()`; ### 输入输出Shape - `translate(text=...)` 支持: - **单条**:`text: str` → 返回 `Optional[str]` - **批量**:`text: List[str]` → 返回 `List[Optional[str]]` - **批量语义**:返回列表必须与输入 **等长且顺序对应**;某条翻译失败时,对应位置为 `None`(HTTP JSON 中表现为 `null`)。 ### 批量能力标识(supports_batch) 服务客户端与服务内后端都可以暴露 `supports_batch`。若后端不支持批量,服务端会逐条拆分并保持 shape。 为便于上层(如 `api/translator_app.py`)做最优调用,client / backend 可暴露: - `supports_batch: bool`(property)