garak 多语言翻译支持(Translation Support):配置target_lang与langproviders实现跨语言 LLM 漏洞扫描
【免费下载链接】garakthe LLM vulnerability scanner项目地址: https://gitcode.com/GitHub_Trending/ga/garak
garak(the LLM vulnerability scanner)默认以英文 probe/detector 关键字对模型进行越狱与注入攻击测试。当被测目标使用其他语言时,translation.rst 文档所描述的翻译支持机制可以把 probe 和 detector 的关键词、触发器翻译成目标语言,让针对「非插件编写语言」模型的测试成为可能。阅读本文后,你将掌握run段中target_lang与langproviders的完整配置方法,能够分别基于 DeepL、NVIDIA Riva、Google Cloud Translation 与本地 Hugging Face 模型搭建双向翻译链路,并理解翻译服务在 garak 内部的加载与调用原理。
为什么 garak 需要翻译支持
garak 的 probe 与 detector 插件在编写时以英文为默认语言,其攻击载荷(payload)、触发器(trigger)与判定关键字均为英文。当被测模型(target under test)接受并产生非英文文本时,直接套用英文载荷会大幅削弱攻击的有效性。翻译支持正是为了解决这一问题:在运行前将 probe 与 detector 的关键字和触发器翻译为target_lang指定的目标语言,从而对非英文模型执行与原英文场景等价的测试。
从源码结构看,这一能力由三个层次组成:
- 翻译器的插件包 garak/langproviders/,其中 base.py 定义了所有语言提供者(LangProvider)的公共基类,local.py 与 remote.py 分别实现本地与远程翻译器;
- 集中调度模块 garak/services/langservice.py,负责按配置实例化、校验并分发翻译器;
- 消费方是各 probe 基类,例如 garak/probes/base.py 中的
_get_langprovider()/_get_reverse_langprovider(),以及 detector 侧的反向翻译判定流程。
当前限制(Limitations)
在使用翻译功能前,需要明确文档中列出的限制:
- 与 BCP47 码 "en" 强耦合:目前句子检测与结构解析强烈依赖
BCP47码 "en",即默认源语言假设为英文; - 反向翻译的必要性:snowball 类 probe 以及 Hugging Face detector 由于模型加载格式的原因,必须进行反向翻译(reverse translation,将目标语言结果再译回英文用于判定);
- Hugging Face detector 的英文模型依赖:Hugging Face 的 detector 主要加载英文模型,因此需要为目标语言额外准备 NLI(自然语言推理)模型用于判定;
- 资源不足时的降级方案:如果 probe 或 detector 加载失败,可能需要选择更小的本地翻译模型,或改用远程翻译服务;
- 运行时间显著增加:翻译会引入额外执行时间,具体取决于可用计算资源。
支持的翻译服务
文档列出了四类官方支持的翻译后端:
| 后端 | 类型 | 说明 |
|---|---|---|
| Hugging Face | 本地 | Helsinki-NLP/opus-mt-{src}-{tgt}(MarianMT 系列)、facebook/m2m100_418M、facebook/m2m100_1.2B |
| DeepL | 远程 | 通过 DeepL API 调用,配置项remote.DeeplTranslator |
| NVIDIA Riva for Developers | 远程 | 通过 Riva API 调用,配置项remote或remote.RivaTranslator |
| Google Cloud Translation API | 远程 | 通过 Google Cloud Translation 调用,配置项remote.GoogleTranslator |
远程服务的具体语言支持范围不在仓库内维护,需参考各服务官方支持矩阵(DeepL 支持语言列表、Riva NMT 支持矩阵、Google Cloud Translation 支持语言)。仓库源码中则各自内置了白名单校验,例如 remote.py 中RivaTranslator.lang_support列出了约 33 种语言并对es/zh/pr等做了区域码覆盖(es-US、zh-TW、pt-PT),DeeplTranslator.lang_support与GoogleTranslator同样会在加载时校验语言对,不支持的组合会抛出BadGeneratorException。
API Key 的获取与注入
使用 DeepL、Riva 或 Google Cloud Translation 等云服务时,必须提供 API key。文档给出了各服务的获取入口(DeepL Pro-API、build.nvidia.com 上的 Riva Megatron-1B NMT、Google Cloud Translation 认证文档),并建议通过环境变量注入,避免把密钥写死在配置文件中:
# DeepL export DEEPL_API_KEY=xxxx # Riva export RIVA_API_KEY=xxxx # Google Cloud Translation(注意:这里要求的是服务账号 JSON 凭据文件的路径) export GOOGLE_APPLICATION_CREDENTIALS=<path to credential configuration json file>对应源码中,每个远程翻译器通过ENV_VAR类属性声明所需的环境变量:remote.py 的RivaTranslator.ENV_VAR = "RIVA_API_KEY"、DeeplTranslator.ENV_VAR = "DEEPL_API_KEY"、GoogleTranslator.ENV_VAR = "GOOGLE_APPLICATION_CREDENTIALS"。其中GoogleTranslator覆写了_validate_env_var(),专门校验该环境变量指向的文件路径真实存在(参见 remote.py)。
值得一提的是,garak 的配置加载器 garak/_config.py 会扫描配置文件中出现的api_key字段:在非 Windows 平台若检测到配置文件对其他人可读,会发出权限告警,建议将敏感信息移出配置文件或收紧文件权限。
配置文件:run段的两把钥匙
翻译功能在配置文件的run段配置,核心是两个键:
target_lang:一个BCP47语言码,指明被测目标的语言,例如"ja"、"fr"、"jap"等;langproviders:一个列表,每个元素是一个语言对定向的翻译器配置。
配置默认值定义在 garak/_config.py:run.target_lang = "en"、run.langproviders = [],即不配置时翻译功能保持关闭、按英文运行。
每个语言提供者配置项遵循项目的 configurable 模式,包含以下键:
| 键 | 必填 | 说明 |
|---|---|---|
language | 是 | 以,分隔的一对BCP47语言码,如en,ja,描述该翻译器支持的翻译方向 |
model_type | 是 | 要实例化的langproviders模块及可选实例类,如local、remote、remote.DeeplTranslator |
model_name | 条件必填 | 翻译加载的模型名;local类型的翻译器必须提供 |
api_key | 可选 | 远程服务密钥(也可以改用环境变量注入) |
此外,翻译模型类型还可能定义自己的专属参数(model-specific parameters)。有两个重要注意事项:
- MarianMT 语言码的不一致:
Helsinki-NLP/opus-mt-{source}-{target}命名中的语言码格式并不统一。双字母码通常可在 Google Admin SDK 语言列表中查到,三字母码则需要搜索确认(如jap、cmn等)。从 local.py 的源码可以看出,model_name中的{}会被替换为source_lang-target_lang拼接而成的模型后缀,所以语言码必须与 Hugging Face 上真实存在的模型名一致,否则会在下载模型时抛出异常。 - 本地翻译不支持跨多进程边界:本地翻译会实际加载模型,设计上不用于跨多进程(multiprocessing)场景;local.py 中通过
mp.set_start_method("spawn", force=True)固定了进程启动方式。
langproviders列表中的每一项都对应单一翻译方向(single translation pair)。由于 snowball 类 probe 与 Hugging Face detector 需要反向翻译,运行前必须同时配置正向与反向两个方向的翻译器,缺一不可。这一校验逻辑实现在 garak/services/langservice.py:加载完成后会遍历所有已加载的语言对,若找不到{target},{source}对应的反向条目,则抛出GarakException并提示「Configuration must specify language providers for each required direction」。另外,若某项配置的source_lang == target_lang,_load_langprovider会直接返回不做任何翻译的Passthru翻译器(garak/services/langservice.py)。
配置文件写好之后,通过--configCLI 选项传入路径即可生效。
通用配置模板
run: target_lang: <target-language-code> langproviders: - language: <source-language-code>,<target-language-code> api_key: <your-API-key> model_type: <translator-module-or-module.classname> model_name: <huggingface-model-name> - language: <target-language-code>,<source-language-code> api_key: <your-API-key> model_type: <translator-module-or-module.classname> model_name: <huggingface-model-name>四种后端的完整配置示例
DeepL
run: target_lang: <target-language-code> langproviders: - language: <source-language-code>,<target-language-code> model_type: remote.DeeplTranslator - language: <target-language-code>,<source-language-code> model_type: remote.DeeplTranslatorexport DEEPL_API_KEY=xxxx python3 -m garak --target_type nim --target_name meta/llama-3.1-8b-instruct --spec probes.encoding --config <path-to-your-yaml-config-file>仓库测试资产 tests/_assets/langservice/translation_deepl.yaml 给出了实际使用的简化版本(en,ja+ja,en双向、target_lang: ja)。
NVIDIA Riva
run: target_lang: <target-language-code> langproviders: - language: <source-language-code>,<target-language-code> model_type: remote - language: <target-language-code>,<source-language-code> model_type: remoteexport RIVA_API_KEY=xxxx python3 -m garak --target_type nim --target_name meta/llama-3.1-8b-instruct --spec probes.encoding --config <path-to-your-yaml-config-file>model_type: remote会加载模块默认类RivaTranslator(见 remote.py 的DEFAULT_CLASS = "RivaTranslator")。Riva 翻译器默认连接grpc.nvcf.nvidia.com:443并携带固定的function_id,实例化时还会用单个 ASCII 字符"A"发起一次校验翻译(VALIDATION_STRING),配置无效会立即报错(参见 remote.py)。对应测试资产为 tests/_assets/langservice/translation_riva.yaml。
Google Cloud Translation
run: target_lang: <target-language-code> langproviders: - language: <source-language-code>,<target-language-code> model_type: remote.GoogleTranslator - language: <target-language-code>,<source-language-code> model_type: remote.GoogleTranslatorexport GOOGLE_APPLICATION_CREDENTIALS=<path to credential configuration json file> python3 -m garak --target_type nim --target_name meta/llama-3.1-8b-instruct --spec probes.encoding --config <path-to-your-yaml-config-file>GoogleTranslator默认参数中还有一个可选project_id,可通过服务账号文件认证(translate.Client.from_service_account_json),认证失败时会回退到通用认证路径;翻译失败时内置 5 次重试并随机退避(0–2 秒),每次翻译结果还会经ftfy修正文本(参见 remote.py)。
本地 Hugging Face 模型
默认:Helsinki-NLP MarianMT
不提供model_name时,本地翻译默认加载Helsinki-NLP/opus-mt-*系列模型:
run: target_lang: jap langproviders: - language: en,jap model_type: local - language: jap,en model_type: localpython3 -m garak --target_type nim --target_name meta/llama-3.1-8b-instruct --spec probes.encoding --config <path-to-your-yaml-config-file>默认model_name为Helsinki-NLP/opus-mt-{}(见 local.py 的DEFAULT_PARAMS),加载时{}会被替换为en-jap、jap-en等真实模型名。注意测试资产 tests/_assets/langservice/translation_local_low.yaml 中保留了显式写法model_name: Helsinki-NLP/opus-mt-{}作为对照。
扩展:facebook/m2m100
本地翻译额外支持 Hugging Face 的M2M100Model类型,只要提供的model_name包含m2m100即按 M2M100 加载:
run: target_lang: ja langproviders: - language: en,ja model_type: local model_name: facebook/m2m100_418M - language: jap,en model_type: local model_name: facebook/m2m100_418Mpython3 -m garak --target_type nim --target_name meta/llama-3.1-8b-instruct --spec probes.encoding --config <path-to-your-yaml-config-file>M2M100 分支会在 local.py 中对源语言与目标语言做白名单校验(内置约 100 种语言码,含ja、zh、fr等),翻译时通过forced_bos_token_id=self.tokenizer.get_lang_id(self.target_lang)指定目标语言;不支持的组合会抛出BadGeneratorException。仓库测试资产 tests/_assets/langservice/translation.yaml 即采用facebook/m2m100_418M双向配置。
翻译服务的加载与双向校验机制
理解了配置后,再来看 garak 内部是如何把这些 YAML 条目变成可用翻译器的。核心入口是 garak/services/langservice.py 的load()函数,流程如下:
- 读取配置:遍历
_config.run.langproviders,逐项调用_load_langprovider()实例化翻译器; - 实例化:
_load_langprovider()把单个条目包装成 configurable 结构,通过_plugins.load_plugin(path=f"langproviders.{model_type}")动态加载插件(garak/services/langservice.py),因此model_type既可以是模块名(local、remote),也可以是带类名的路径(remote.DeeplTranslator、remote.GoogleTranslator); - 补齐原生方向:若配置中不存在
{target_lang},{target_lang}的原生语言对象,会自动补一个local类型的 no-op 翻译器(garak/services/langservice.py); - 双向校验:确认每个已配置方向都存在反向条目,缺失则抛异常中止运行(garak/services/langservice.py)。
运行时,probe/detector 通过get_langprovider(source, reverse=False)获取单方向翻译器(garak/services/langservice.py),reverse=True时返回目标语言译回源语言的反向翻译器。在 garak/probes/base.py 中,probe 初始化即分别取得正向与反向两个翻译器,翻译后的载荷会打上lang标签,并在探测结果返回后使用反向翻译器把模型输出再译回英文供 detector 判定(参见 garak/probes/base.py 附近的reverse_langprovider.get_text(results_text)调用)。
在文本处理层面,base.py 的split_input_text()会按换行拆分输入,并对包含:(且不含 URL)的行进一步按冒号切分,尽量保留结构;_short_sentence_translate/_long_sentence_translate分别处理 200 字符以内与更长的文本;对于不可见 Unicode 字符行、纯空白行、$等特殊行会跳过翻译或原样保留,避免破坏编码类 probe 的载荷结构(相关逻辑见 base.py)。测试 tests/langservice/test_langprovision.py 对split_input_text的冒号切分行为有明确断言,同时验证了本地翻译器对多行载荷逐行翻译、保留非文本行的行为(tests/langservice/test_langprovision.py)。
使用建议与注意事项
- 语言码一致性:
target_lang、language中的语言码必须与所选后端支持的格式一致(MarianMT 需匹配 Hugging Face 模型名,M2M100/Riva/DeepL 需在各自白名单内),远程服务还受各厂商官方支持矩阵约束; - 务必配置双向:运行前确认
langproviders同时包含源,目标与目标,源两个方向的条目,否则langservice.load()会直接中止运行; - 密钥安全:优先使用环境变量注入 API key;若写在配置文件中,注意 garak 会检查文件权限并给出告警(garak/_config.py);
- 资源规划:本地翻译会下载并加载完整的 Hugging Face 模型(M2M100 系列体积较大),首次运行耗时明显;模型加载失败时可换用更小的本地模型或改用远程服务,并预留足够的磁盘与内存空间;
- 整体开销:翻译会为每次探测引入额外的前后向翻译调用,整体执行时间会随 prompt 数量与文本长度显著增长,可结合
--parallel_requests等并发参数权衡。
相关代码与测试路径:翻译器插件 garak/langproviders/、调度与校验 garak/services/langservice.py、配置默认值 garak/_config.py、probe 侧消费 garak/probes/base.py、测试用例 tests/langservice/test_langprovision.py 与配置样例 tests/_assets/langservice/。
【免费下载链接】garakthe LLM vulnerability scanner项目地址: https://gitcode.com/GitHub_Trending/ga/garak
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考