5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
"""Translation service orchestration."""
from __future__ import annotations
import logging
from typing import Dict, List, Optional
from config.services_config import TranslationServiceConfig, get_translation_config
from translation.protocols import TranslateInput, TranslateOutput, TranslationBackendProtocol
logger = logging.getLogger(__name__)
class TranslationService:
"""Owns translation backends and routes calls by model and scene."""
def __init__(self, config: Optional[TranslationServiceConfig] = None) -> None:
self.config = config or get_translation_config()
self._backends: Dict[str, TranslationBackendProtocol] = {}
self._init_enabled_backends()
def _init_enabled_backends(self) -> None:
registry = {
"qwen-mt": self._create_qwen_mt_backend,
"deepl": self._create_deepl_backend,
"llm": self._create_llm_backend,
}
for name in self.config.enabled_models:
factory = registry.get(name)
if factory is None:
logger.warning("Translation backend '%s' is enabled but not registered", name)
continue
self._backends[name] = factory()
if not self._backends:
raise ValueError("No enabled translation backends found in services.translation.capabilities")
def _create_qwen_mt_backend(self) -> TranslationBackendProtocol:
from translation.backends.qwen_mt import QwenMTTranslationBackend
cfg = self.config.get_capability_cfg("qwen-mt")
return QwenMTTranslationBackend(
model=cfg.get("model") or "qwen-mt-flash",
api_key=cfg.get("api_key"),
use_cache=bool(cfg.get("use_cache", True)),
timeout=int(cfg.get("timeout_sec", 10)),
glossary_id=cfg.get("glossary_id"),
translation_context=cfg.get("translation_context"),
)
def _create_deepl_backend(self) -> TranslationBackendProtocol:
from translation.backends.deepl import DeepLTranslationBackend
cfg = self.config.get_capability_cfg("deepl")
return DeepLTranslationBackend(
api_key=cfg.get("api_key"),
timeout=float(cfg.get("timeout_sec", 10.0)),
glossary_id=cfg.get("glossary_id"),
)
def _create_llm_backend(self) -> TranslationBackendProtocol:
from translation.backends.llm import LLMTranslationBackend
cfg = self.config.get_capability_cfg("llm")
return LLMTranslationBackend(
model=cfg.get("model"),
timeout_sec=float(cfg.get("timeout_sec", 30.0)),
base_url=cfg.get("base_url"),
)
@property
def available_models(self) -> List[str]:
return list(self._backends.keys())
def get_backend(self, model: Optional[str] = None) -> TranslationBackendProtocol:
normalized = self.config.normalize_model_name(model)
backend = self._backends.get(normalized)
if backend is None:
raise ValueError(
f"Translation model '{normalized}' is not enabled. "
f"Available models: {', '.join(self.available_models) or 'none'}"
)
return backend
def translate(
self,
text: TranslateInput,
target_lang: str,
source_lang: Optional[str] = None,
*,
model: Optional[str] = None,
scene: Optional[str] = None,
prompt: Optional[str] = None,
) -> TranslateOutput:
backend = self.get_backend(model)
active_scene = (scene or self.config.default_scene or "general").strip() or "general"
return backend.translate(
text=text,
target_lang=target_lang,
source_lang=source_lang,
context=active_scene,
prompt=prompt,
)
|