尝试使用Index翻译模型

月初的时候,Bilibili的LLM团队发布了Index(茵蒂克丝)翻译模型及其量化版本,宣传的非常好。于是我决定尝试一下。

之前,我一直主力使用Hy-MT2系列模型,用于沉浸式翻译和本地小说翻译。

1. 部署量化版本(2B & 9B)

和部署Hy-MT2模型时类似,2B模型选择Q8量化,9B模型选择Q4量化。

前期做了很多测试,但是都不是很理想,BLEU分数徘徊在39~43之间,远不如Hy-MT2模型。后来发现,这个模型对于提示词非常敏感,使用不同的提示词的差别很大:

模型 K&V 缓存量化 BLEU chrF++ PROMPT
Index-Translate-2B:Q8_0 q8_0 50.65 34.41 Index中文
39.17 20.77 Index英文
56.68 35.17 Hy中文
42.37 21.23 Hy英文
Index-Translate-9B:Q4_K_M q8_0 52.64 34.79 Index中文
38.18 20.55 Index英文
53.88 35.17 Hy中文
39.17 20.77 Hy英文

具体的提示词如下,都是来自于官方的示例:

  • Index中文:
    • 请将以下文本翻译为中文,直接输出翻译结果,不要进行任何解释:
  • Index英文:
    • Translate the following text into Chinese. Output the translation directly, without any explanation:
  • Hy中文:
    • 将以下文本翻译为中文,注意只需要输出翻译后的结果,不要额外解释:
  • Hy英文:
    • Translate the following text into Chinese. Note that you should only output the translated result without any additional explanation:

可以看到:

  • 使用中文提示词的分数要远高于使用英文提示词的分数。
  • 使用Hy示例的提示词的分数要高于使用Index示例的提示词的分数。
  • 9B模型的分数经常低于2B模型的分数。

好奇怪。。。

2. 部署非量化版本(2B)

使用vLLM(v0.29.0)部署非量化的2B模型,命令如下:

1
2
3
4
5
6
7
8
9
10
11
docker run --gpus all -it --rm \
--ipc=host --ulimit memlock=-1 --ulimit stack=67108864 \
--name vllm \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-e "HF_ENDPOINT=$HF_ENDPOINT" \
-e VLLM_WSL2_ENABLE_PIN_MEMORY=1 \
-p 8118:8000 nvcr.nju.edu.cn/nvidia/vllm:26.09-py3 \
vllm serve IndexTeam/Index-Translate-2B \
--tensor-parallel-size 1 --max-model-len 8192 \
--gpu-memory-utilization 0.8 --num-max-seqs 128 \
--language-model-only

最开始测试的时候没有指定temperature=0,测出来的BLEU分数波动非常大,最低的一次甚至只有12.95。指定之后,又发现中间会卡住,多次测试定位之后,发现是在翻译的时候陷入了「啊啊啊」的死循环。

前面在使用LM Studio部署量化版本的时候没有遇到这个问题,因为它的默认参数包含repetition_penalty=1.1,于是没有遇到这个问题。

开启frequency_penalty=0.4,能够解决这个问题。

实测,frequency_penalty开到0.1~0.8都可以,开到1.0分数略微降低。

开启repetition_penalty=1.1,则BLEU分数略微减低,chrF分数增加。

同样的,使用vLLM部署的模型也对提示词非常敏感:

模型 K&V 缓存量化 BLEU chrF++ PROMPT
Index-Translate-2B f16 39.62 18.15 Index中文
39.62 18.15 Index英文
57.37 32.28 Hy中文
43.00 18.55 Hy英文

使用frequency_penalty=0.4和repetition_penalty=1.1测试:

模型 K&V 缓存量化 BLEU chrF++ PROMPT
Index-Translate-2B f16 50.65 34.41 Index中文
39.17 20.77 Index英文
56.68 35.17 Hy中文
42.37 21.23 Hy英文

上面的测试都是针对特定的一个数据集,而实际情况更为复杂。

对于2B大小的模型,使用vLLM部署非量化版本的运行速度要超过使用LM Studio部署的量化版本。

对于测试这种可以并行的情况更加明显。

官方建议输出tokens控制在1k以内,确实是明智的,一旦超出,经常无法保持换行,后面的输出内容都挤到一段里了。

看来这就是1.8B~2B大小的模型的输出极限了。

即使换成是Nailong模型,在输出超过2k之后,也经常会在遇到连续拟声词的时候陷入死循环。

3. 使用官方API(35B-A3B)

官网开放了直接调用API的方法,最开始只支持35B-A3B模型,后来也支持2B和9B模型(不过没有试过)。

我把它进入了沉浸式翻译和Cherry Studio内进行实测。

对于沉浸式翻译,体感上优于Hy-MT2-7B:Q4,但是比不上Hy-MT2-30B-A3B:Q4。

但是官方API胜在速度非常快,能够达到120 tokens/s,比本地运行Hy-MT2-1.8B:Q8还要快得多。

官方API的限制经历过几次调整,最开始是max_tokens=4096,后来是output_tokens=2048。截至写稿时是output_tokens=4096,翻译长文更加方便,但是速度只有40 tokens/s了。

不过即使是这么大的模型,依然避免不了遇到连续拟声词退化的情况。

另外,35B-A3B模型对于提示词依然很敏感。我多次遇到使用Index风格的提示词不行、但是换成Hy风格的提示词就可以的情况。

对于日文小说,经过多次相同文本翻译的对比,感觉Index-Translate-35B-A3B还是不如Hy-MT2-30B-A3B:Q4的效果好。

4. 总结

经过上面的测试,目前我的使用策略是:

  • 对于沉浸式翻译,使用Index模型,开着官方的API脚本,这样既能保证速度,也不会占用本地资源。
  • 对于小说的翻译,依然使用Hy-MT2-30B-A3B模型,使用LM Studio自动加载和卸载模型。