Googleの TranslateGemma という翻訳特化型のモデルが軽量ながら、翻訳精度が高く、最軽量の4Bモデルでも問題ないレベルの翻訳文を得られる。
以前よりローカルで起動するLLMあるいはSLMに興味はあったものの、一般的なスペックのノートPCしか持ち合わせていないため利用できなかった。TranslateGemma 4BはノートPCレベルでも動作できて、日常利用に支障のない精度を得られるモデルであると個人的にはじめて感じたので、これはOllamaを使うのではなく、自分で量子化してllamal.cpp(llama-server)で動作させてみたいと思った。
今回は、自分自身で、GGUFの量子化モデルをTranslateGemma 4Bモデルで作成した際のメモをまとめる。
必要なもの
GGUFなおかつ4bitに量子化するには、llama.cpp の下記のものが両方必要になる。
- ソースコード
- バイナリ
ソースコードは、GitHubのリポジトリから入手する。
git clone https://github.com/ggml-org/llama.cpp.git
バイナリは、今回自分は GitHubのReleaseページ で配布されているものを利用した。
環境構築
普段Pythonの環境ではuvを使っているので、今回の動作用の環境を構築。ただ、リポジトリに入っているpyproject.tomlはPoetry用のものなので、削除してからuvで環境を構築。
cd llama.cpp
rm pyproject.toml
uv init
uv sync
. .\.venv\Scripts\activate
uv add -r ./requirements.txt
モデルのダウンロード
Hugging FaceのTranslateGemma 4B のページからモデルをダウンロードする。
- 最初に、Googleに対してアクセス許可を申請する必要がある。ページ上部のフォームから利用申請を送信する
- ページ右側の縦3点のボタン→「Clone repository」で表示される内容に沿って、モデルをダウンロードする。4Bとはいえ大きなファイルサイズのモデルとなるため、ダウンロードには git-xet というツールのインストールが必要になる。それについても記載されているので参考にしながらインストールする
- Hugging Faceで公開されているモデルにアクセスするための トークン も事前に作成しておく
- 下記のコマンドでモデルをダウンロードする
git clone https://[HFのユーザー名]:[先ほど作成したHFのアクセストークン]@huggingface.co/google/translategemma-4b-it
chat_template.jinjaの修正
llama-serverを使う場合、OpenAI互換APIに則った使い方(パラメータの送信)が必要になる。そのため、TranslateGemma 4Bが持つsource_lang_code(翻訳元の言語コード)やtarget_lang_code(翻訳先の言語コード)といった独自のパラメータが利用できない。そこで、ダウンロードしたモデル一式に含まれるchat_template.jinjaを修正し、Open互換APIの形式で送られた情報をchat_template.jinjaで整形してモデルへ渡すようにする。
今回の場合、contentパラメータを下記のようにし、chat_template.jinjaで [sprt] という文字列により翻訳元と翻訳先の言語コードならびに翻訳したい文章を分割している。
翻訳元の言語コード[sprt]翻訳先の言語コード[sprt]翻訳したい文章
たとえば、下記のような入力を想定している。これで Mount Fuji is the highest mountain in Japan. のような翻訳文を得られる。
ja[sprt]en[sprt]日本で一番高い山は富士山です。
chat_template.jinjaの修正内容は下記のとおり(配布内容そのままでは別の理由でエラーになった部分も修正している)。
{%- set languages = {
"aa": "Afar",
"aa-DJ": "Afar",
"aa-ER": "Afar",
...(500行以上あるため省略)...
"zh-Latn": "Chinese",
"zu": "Zulu",
"zu-ZA": "Zulu"
} -%}
{{ bos_token }}
{%- for message in messages -%}
{%- if message['role'] == 'user' -%}
{{ '<start_of_turn>user\n' }}
{%- set separator = "[sprt]" -%}
{%- set parts = message["content"].split(separator) -%}
{# 分割して3つのパーツ(src, tgt, text)があるかチェック #}
{%- if parts | length == 3 -%}
{%- set source_lang_code = parts[0].replace("_", "-") | trim -%}
{%- set target_lang_code = parts[1].replace("_", "-") | trim -%}
{%- set translation_text = parts[2] | trim -%}
{# 言語名を取得(辞書にない場合はコードをそのまま表示) #}
{%- set source_lang = languages.get(source_lang_code, source_lang_code) -%}
{%- set target_lang = languages.get(target_lang_code, target_lang_code) -%}
{{ 'You are a professional ' + source_lang + ' (' + source_lang_code + ') to ' +
target_lang + ' (' + target_lang_code + ') translator. Your goal is to accurately convey the meaning and ' +
'nuances of the original ' + source_lang + ' text while adhering to ' + target_lang + ' grammar, ' +
'vocabulary, and cultural sensitivities.\n' +
'Produce only the ' + target_lang + ' translation, without any additional explanations or ' +
'commentary. Please translate the following ' + source_lang + ' text into ' + target_lang + ':\n\n\n' +
translation_text
}}
{%- else -%}
{# 書式が違う場合はそのまま出力(通常のプロンプトとして扱う) #}
{{ message['content'] | trim }}
{%- endif -%}
{{ '<end_of_turn>\n' }}
{%- elif message['role'] == 'assistant' -%}
{{ '<start_of_turn>model\n' }}
{{ message['content'] | trim }}
{{ '<end_of_turn>\n' }}
{%- endif -%}
{%- endfor -%}
{%- if add_generation_prompt -%}
{{ '<start_of_turn>model\n' }}
{%- endif -%}
本来、TranslateGemma 4BはI2T(画像入力)に対応しているが、今回の修正により、画像入力は非対応となる。
量子化
量子化は、下記の手順で順番に実施する。
- GGUF化
- 4bit量子化(Q4_K_M)
GGUF化
GGUF化はllama.cppのソースコード(Pythonのもの)を利用する。
書式
python [githubからcloneしたllama.cppのdir]/convert_hf_to_gguf.py [hfからcloneしたtranslategemmaのdir] --outfile [ggufを保存したいdir]/translategemma-4b-it.gguf --outtype bf16
入力例
python convert_hf_to_gguf.py hf-models/translategemma-4b-it --outfile hf-models/translategemma-4b-it.gguf --outtype bf16
4bit量子化
4bit量子化をする場合は、バイナリのllama-quantizeを利用する。
書式
[buildされたllama.cppのdir]/llama-quantize [先ほど作成したggufのあるdir]/translategemma-4b-it.gguf [量子化モデルを保存したいdir]/translategemma-4b-it-Q4_K_M_GGUF.gguf Q4_K_M
入力例
./builds/llama-quantize hf-models/translategemma-4b-it.gguf models/translategemma-4b-it-Q4_K_M_GGUF.gguf Q4_K_M
llama-serverの起動
作成した量子化モデルを、下記のようなコマンドで実行する。
[buildされたllama.cppのdir]/llama-server -m [量子化モデルのあるdir]/translategemma-4b-it-Q4_K_M_GGUF.gguf --port 8080 --jinja
今回作成したファイル
上記の流れで作成したGGUFファイルを下記に格納している。