Hy-MT2 1.8BをM1 Maxで動かす、1.25bit 440MB版は標準llama.cppでまだ動かない
目次
Tencent Hunyuanの翻訳モデルHy-MT2がHugging FaceとModelScopeに出ていた。
サイズは1.8B、7B、30B-A3Bの3系統。
33言語の相互翻訳に対応し、1.8BにはGGUF、2bit GGUF、1.25bit GGUFまで用意されている。
目立つのは30B-A3Bのベンチマークより、1.8Bを440MBまで落とした方だ。
ローカル翻訳は「APIに投げるほどでもない短文」「社外に出しにくい文書」「回線が怪しい端末内処理」で欲しくなる。
以前MyMemory APIをブラウザから直接叩く記事を書いたが、あれは外部API前提だった。
Hy-MT2は同じ翻訳用途を、端末側でローカル完結させるためのモデル群として出てきた。
M1 Max 64GBで1.8B Q4_K_M (1.08GB) を llama-server (build 8990) に載せて、JSON・SRT・HTML・用語拘束・少数言語まで投げた結果は記事後半にまとめた。
1.25bit約440MB版は、標準llama.cppではまだ動かない件もそちらで触れる。
公開されたモデルの中身
Hugging Faceのモデルカードでは、2026年5月21日にHy-MT2-1.8B、Hy-MT2-7B、Hy-MT2-30B-A3B、IFMTBenchを公開したと書かれている。
1.8Bと7Bはdense系、30B-A3BはMoE(Mixture of Experts)だ。
MoEは全パラメータを毎トークンで使わず、入力ごとに一部のエキスパートを選んで動かす構造で、30B-A3Bの「A3B」はアクティブパラメータが約3Bという意味で読める。
flowchart TD
Text[入力文] --> Router[MoEルーター]
Router --> E1[翻訳エキスパート]
Router --> E2[文体・用語エキスパート]
Router --> E3[形式保持エキスパート]
E1 --> Out[翻訳結果]
E2 --> Out
E3 --> Out
実装面ではTransformers、vLLM、SGLangの例が載っている。
1.8Bと7Bは temperature: 0.7、top_p: 0.6、top_k: 20、repetition_penalty: 1.05 が推奨値。
30B-A3Bは top_p: 1.0、top_k: -1、repetition_penalty: 1.0 になっていて、同じ翻訳モデルでも推論設定は分けられている。
33言語と少数言語を同じ枠に入れる
対応言語には日本語、英語、中国語、韓国語、フランス語、ドイツ語、スペイン語、ロシア語、アラビア語、ベトナム語、タイ語などが並ぶ。
さらにチベット語、カザフ語、モンゴル語、ウイグル語、広東語も含まれている。
論文ではMandarin-minority translationとして、中国語と少数民族言語の双方向翻訳を別評価にしている。
ここは汎用LLMの翻訳と少し違う。
ChatGPTやGeminiに翻訳させると主要言語ではかなり強いが、業務で困るのは言語そのものより、用語指定、書式、固有名詞、翻訳しないコード片の保持だったりする。
Hy-MT2はその部分を翻訳指示追従として前面に出している。
IFMTBenchは翻訳タスク専用の指示追従ベンチマーク
Hy-MT2と一緒に公開されたIFMTBenchは、翻訳タスク専用の指示追従ベンチマークだ。
論文では7,344件のhuman-alignedサンプルを使い、用語、形式、文体などの制約を含むと説明している。
単一制約が4,506件、複合制約が2,838件。
モデルカードのプロンプト例も普通の「英語に翻訳して」だけではない。
指定用語を守る、文体を指定する、区切り文字を同数・同位置で残す、JSONやHTMLのような構造データのキーやタグを翻訳しない、背景情報を反映する、といった例が載っている。
翻訳アプリで壊れるのはこのあたりだ。
UI文言、字幕、契約書、コードコメント、JSONリソースを扱うと、文としては正しくてもフォーマットを壊した時点で使い物にならない。
WebRTC音声をリアルタイム翻訳へつなぐ記事では翻訳API選びを軽く触ったが、会話字幕でもSRTや発話者ラベルを維持できるかで実装が変わる。
440MB版はAngelSlimの1.25bit量子化
1.8BモデルにはAngelSlimによる1.25bit GGUFが用意されている。
論文とモデルカードは、1.8Bモデルが1.25bit極低ビット量子化で約440MBになり、推論速度も従来の4bit量子化より1.5倍になると書いている。
AngelSlim側では2026年5月8日にSTQ1_0カーネルを公開し、llama.cppへPRを出したという更新もある。
量子化は単にファイルを小さくするだけではない。
FP16やBF16は1パラメータあたり16bit、4bit量子化は4bit、2bitは2bitで重みを表す。
1.25bitはさらに下げるため、通常の整数量子化より制約がきつい。
論文ではSherryという1.25bit sparse ternary quantizationを使い、低精度モデルを教師モデルから蒸留するQAT寄りの手順で作っている。
圧縮率だけ見ると強いが、論文の量子化評価では2bitや1.25bitは指示追従側で落ちやすい。
FP8は1.8B、7B、30B-A3BでBF16に近い性能を保ち、Q4_K_MもFLORES-200やドメイン翻訳では残る。
端末内で短文翻訳するなら1.25bit、書式保持や用語拘束まで任せるなら4bit以上かFP8、で切り分けることになる。
ベンチマークはTencent側の評価値
論文ではFLORES-200、WMT25、Mandarin-minority、DomainMTBench、WildMTBench、IFMTBenchを使っている。
一般翻訳ではXCOMET-XXL、CometKiwi、GEMBAを併用する。
WMT25ではHy-MT2-30B-A3Bが62.89 / 71.08 / 84.34を出し、GEMBAではGemini 3.1 ProとGPT-5.5を上回ったと説明している。
FLORES-200のXX⇔XXではHy-MT2-30B-A3Bが87.47で、Gemini 3.1 Proの98.6%相当と書かれている。
1.8Bについては、WMT25でMicrosoft TranslatorとDoubao Translatorを3指標すべてで上回ったと論文が述べている。
WildMTBenchでも商用翻訳システムを上回るとされる。
ただし、これはTencent Hunyuanの論文内評価で、自分の手元の日本語長文、固有名詞、同人系の癖、UI文言で再現した話ではない。
Hugging Face上では1.8BモデルにInference APIが出ている一方、30B-A3Bはモデルカード上でInference Provider未配備と表示されていた。
Spacesはあるが、公開数日後の段階では第三者のまとまった日本語検証はまだ薄い。
「GPT-5.5匹敵」とだけ読んで置き換えるより、手元の翻訳メモリやAPI出力と同じ入力で横並びに比べる。
ローカル翻訳で試すなら1.8B GGUFから
モデルカードにはTransformersの例があるが、ローカル翻訳の入り口としては1.8B GGUFが扱いやすい。
すでにFastAPI・Chroma・Open WebUI・OllamaでローカルRAGを組んだときと同じように、llama.cpp系のサーバーに載せてOpenAI互換APIの裏側へ置ける。
最初の入力は、短いニュース文ではなく、壊れると困る文だ。
たとえばJSONの文言だけ翻訳する、SRTの番号とタイムコードを残す、HTMLタグを残す、ゲーム内の固有名詞を訳さない、契約書の同じ用語を同じ訳語に寄せる。
Hy-MT2はそこを翻訳指示追従の重点として置いている。
M1 Max 64GBで1.8B Q4_K_Mを動かす
ここまでが論文と公式情報。
実際にローカルで動くのかを確認するため、M1 Max 64GBで tencent/Hy-MT2-1.8B-GGUF の Q4_K_M を llama-server に載せて翻訳を投げた。
検証環境
| 項目 | 値 |
|---|---|
| マシン | MacBook Pro M1 Max 64GB unified memory |
| OS | macOS 26.5 (Darwin 25.5.0) |
| llama.cpp | build 8990 (Homebrew) |
| ggml | 0.10.1 |
| モデル | tencent/Hy-MT2-1.8B-GGUF の Hy-MT2-1.8B-Q4_K_M.gguf (1.08GB) |
| アーキ | hunyuan_v1_dense (llama.cpp PR #14878 で2025年8月マージ済み) |
| バックエンド | Metal (M1 Max) |
| コンテキスト | 4096トークン (KVキャッシュ256MB) |
| 推論パラメータ | temperature=0.7, top_p=0.6, top_k=20, repeat_penalty=1.05 (モデルカードの1.8B/7B推奨値) |
llama-server の起動コマンドは次のとおり。
llama-server -m Hy-MT2-1.8B-Q4_K_M.gguf \
-c 4096 -ngl 99 --port 8765 --jinja \
--temp 0.7 --top-p 0.6 --top-k 20 --repeat-penalty 1.05
--jinja でモデルカード同梱のチャットテンプレート (<|hy_User|> / <|hy_Assistant|>) が自動適用される。
これを付け忘れると素の補完モードになって、翻訳指示が指示として解釈されない。
速度
各テストで /v1/chat/completions に1回投げて返ってきたレスポンスの timings.predicted_ms と timings.predicted_per_second を拾った。プロンプトはそれぞれ次の「試したプロンプトと結果」セクションのとおりで、ケースごとに別物。
| ケース | 出力長 (目安) | 所要時間 | 速度 |
|---|---|---|---|
EN→JA 短文 (The quick brown fox jumps over the lazy dog.) | 約22tok | 370ms | 59.5 tok/s |
| JA→EN ニュース文 (山手線運転見合わせ4文) | 約33tok | 590ms | 56.1 tok/s |
| JSON UI文字列 (6項目) | 約106tok | 1.9s | 56.1 tok/s |
| SRT 3ブロック | 約312tok | 5.4s | 57.4 tok/s |
| 用語拘束 (短文・キャッシュ温) | 約30tok | 220ms | 139 tok/s |
M1 Max 64GBで秒間50〜60トークン台が安定して出た。
書式保持を含めた長めのプロンプトでもこの帯から落ちず、プロンプトプリフィックスが効いた状態だと140 tok/sまで上がる。
短文ならレスポンスは1秒以下、SRT 3ブロックでも5秒台で返ってくる。
試したプロンプトと結果
「翻訳指示追従」を売りにしている部分の挙動を自分の目で見ておきたかったので、素の翻訳に加えて JSON・HTML・glossary・SRT・Markdown・少数言語の8パターンを投げた。
EN→JA 短文(速度ベース測定用)
指示文は「Translate the following text into Japanese. Note that you should only output the translated result without any additional explanation.」。投げた英文は次のとおり。
The quick brown fox jumps over the lazy dog.
返ってきた訳文。
素早い茶色のキツネが、怠け者の犬を飛び越える。
意味、語順、語彙とも自然な日本語に着地している。1.8B Q4_K_Mでもこの粒度の文ならふつうに通る。
JA→EN ニュース文
指示文は「以下のテキストを英語に翻訳してください。翻訳結果のみを出力し、追加の説明は不要です。」。投げた日本語は次のとおり。
本日午後、東京都心では激しい雷雨があり、JR山手線の一部区間で運転を見合わせた。気象庁は引き続き警戒を呼びかけている。
返ってきた訳文。
This afternoon, severe rainstorms occurred in Tokyo, causing traffic delays on some sections of the JR Yamanote Line. The Meteorological Agency continues to issue warnings.
「運転を見合わせた」は厳密には suspended service のほうが鉄道用語として正確で、traffic delays だと道路寄りのニュアンスが混じる。ニュース要約として読む分にはこれで通る。鉄道業務文書に流すなら名詞句を後で直す。
JSON UI文字列の翻訳
モデルカード同梱の Structured Data 1 テンプレート (「Translate the user-facing text within the following JSON data into Japanese. Preserve structure, keys, and placeholders exactly.」とそれに続く厳格ルール3項) を指示文として、次のJSONを投げた。
{
"login": {
"title": "Sign in",
"placeholder": "Enter your email",
"button": "Continue",
"error_required": "Email is required",
"welcome": "Welcome back, {{username}}!",
"footer": "By signing in you agree to our Terms of Service."
}
}
返ってきた出力は次のとおり。
{
"login": {
"title": "ログイン",
"placeholder": "メールアドレスを入力してください",
"button": "続行",
"error_required": "メールが必要です",
"welcome": "お帰りいただきありがとう、{{username}}!",
"footer": "ログインすることで、当社の利用規約に同意したことになります。"
}
}
JSON構造、key、{{username}} プレースホルダが原型のまま残った。
welcome の訳は「お帰りいただきありがとう」と固くなった。「おかえりなさい」のほうが自然だが、構造を崩さず訳した結果、訳語の自然さが落ちた。
HTML翻訳 (タグ・属性保持)
指示文は「Translate the following HTML into Japanese. Preserve all HTML tags exactly. Do not translate tag names or attribute keys. Only translate visible text.」をそのまま使った。投げたHTMLは次のとおり。
<div class="card">
<h2>Pricing</h2>
<p>Choose the plan that fits your team.</p>
<a href="/signup" class="btn">Start free trial</a>
</div>
返ってきた出力は次のとおり。
<div class="card">
<h2>料金</h2>
<p>チームに合ったプランを選択してください。</p>
<a href="/signup" class="btn">無料トライアルを開始</a>
</div>
class、href、タグ名が一切変わらず、可視テキストだけが置き換わった。
UI言語ファイルや静的サイトのi18nテンプレートに、この出力をそのまま貼って動作する。
用語拘束 (glossary)
モデルカード同梱の Terminology テンプレートに沿って、わざと不自然な訳語を強制する。プロンプトの抜粋は次のとおり。
Reference the following translations:
agent translates to 代理人
workflow translates to 作業の流れ
prompt translates to 指示文
Translate the following text into Japanese. ...
The agent runs a multi-step workflow and refines the prompt automatically.
返ってきた訳文は 代理人が複数段階の作業の流れを実行し、指示文を自動的に最適化します。
参考用語の指定なしだと、同じ英文が「エージェントは複数段階のワークフローを実行し、プロンプトを自動的に最適化します。」になる。
指示の訳語が出力にそのまま反映された。社内用語集や同人系の固有名詞を毎回当てさせたい用途なら、1.8Bでも処理できる。
SRT字幕の構造保持
指示文はモデルカードの Structured Data 1 をベースに、SRT用に書き換えた版 (「Preserve subtitle index numbers and timecodes exactly」を明示) を使った。投げたSRTは次のとおり。
1
00:00:01,200 --> 00:00:04,500
Good morning everyone, welcome to today's briefing.
2
00:00:05,000 --> 00:00:08,300
We will start with the quarterly results.
3
00:00:08,800 --> 00:00:12,000
Revenue grew by 18 percent year over year.
返ってきた出力は次のとおり。
### タスク
以下のSRT字幕データ内のユーザー向けテキストを、以下の厳格な規則に従って翻訳してください。
### 厳格な規則
1. **構造の保持:** 字幕インデックス番号とタイムコードをそのままに、元のSRTデータ構造を保持する必要があります。
2. **選択的翻訳:** 見える字幕テキストのみを翻訳します。
3. **厳格な非翻訳:** インデックス番号、タイムコード(例:00:00:01,200 --> 00:00:04,500)、矢印マークを決して変更したり翻訳したりしないでください。元の形そのままに置いておきます。
### ソースデータ
1
00:00:01,200 --> 00:00:04,500
皆さん、こんにちは。本日のブリーフィングへようこそ。
2
00:00:05,000 --> 00:00:08,300
四半期決算から始めます。
3
00:00:08,800 --> 00:00:12,000
収益は前年比18%増加しました。
SRTブロック自体は番号・タイムコード・矢印すべて原型のまま残り、本文だけ日本語に置き換わった。番号と矢印の保持はちゃんと効いている。
ただし、SRTブロックの前にプロンプトの「### タスク」「### 厳格な規則」の説明文まで日本語に翻訳して返してきた。
ユーザーロールに「翻訳指示+翻訳対象」を1メッセージで混ぜると、1.8Bでは指示文ごと翻訳対象とみなすことがある。
実運用ではシステムプロンプトに指示文を切り出すか、Structured Data 1 のように区切りをコロン・改行で明示的に挟む。
Markdown内のコードブロック保持
指示文は「Translate the following Markdown into Japanese. Preserve code blocks (the part inside ```) exactly without translation. Only translate prose.」。投げたMarkdownは次のとおり。
Use the following command to start the server.
```bash
llama-server -m model.gguf --port 8765
```
The server listens on port 8765 by default.
返ってきた出力は次のとおり。
サーバーを起動するには、次のコマンドを使用します。
```bash
llama-server -m model.gguf --port 8765
```
サーバーはデフォルトでポート 8765 で listening します。
コードブロックは中身もフェンスも完全に保持された。地の文だけが日本語化されている。
ただし末尾の listening が英語のまま残った。同じプロンプトを何度か投げ直すと、出力ごとに訳語が「リッスンします」「接続を受け付けます」「リスナーになります」と変わる。temperature=0.7 の出力ゆれで、固定した訳語に揃えたいなら glossary 指定を入れるか、後段で訳語置換を入れる。
少数言語 (モンゴル語・チベット語)
「33言語対応」のうち、少数言語側の品質を見るため英→モンゴル語と英→チベット語を投げた。
英→モンゴル語は Good morning. The weather is beautiful today. を投げた結果が次のとおり。
ᠰᠢᠷᠦᠭᠦᠯᠡᠩ ᠰᠠᠷᠠᠯᠲᠠ ᠃ ᠡᠳᠦᠷ ᠡᠨᠡ ᠡᠪᠦᠯ ᠰᠠᠢᠬᠠᠨ ᠪᠠᠢᠨ۳ᠠ ᠃
内モンゴルで使われる伝統モンゴル文字 (縦書き用) で出力された。モンゴル国の公用文字はキリル文字なので、特定のロケールに寄せたいなら指示側で明示する。さらに ۳ (アラビア数字3) が混入していて、1.8B Q4_K_Mでは細部の文字種が乱れる場面があった。
英→チベット語は同じ英文を投げて、返ってきたのが次の出力。
ཞིག་ཤོས་ཀྱི་དགོངས་པ་ཡིན། आजའི་གནམ་གཤིས་ཧ་ཅང་སྐྱིད་པོ་རེད།
チベット文字のなかにデーヴァナーガリーの आ が混ざっていて、スクリプトの取り違えが1.8B側で起きている。
JA→モンゴル語も投げてみた。指示文は「以下のテキストをモンゴル語に翻訳してください。翻訳結果のみを出力し、追加の説明は不要です。」で、投げた日本語は次のとおり。
今日の会議は午後3時に開始します。
返ってきた出力。
今日の会議は午後3時に始まります。
モンゴル語ではなく、日本語のまま「開始します」を「始まります」に言い換えただけで返してきた。指示は通っているのに、ターゲット言語側の生成までは届いていない。
少数言語の入出力は1.8Bでは安定しない。ここを期待するなら7Bか30B-A3Bが対象になる。
ただし30B-A3Bは後述のとおり、Macの標準ルートで動かす経路がまだ整っていない。
1.25bit 440MB GGUFは標準llama.cpp 8990ではまだ動かない
公開直後にいちばん目を引いた1.25bit約440MBは、Homebrewで入る標準llama.cpp build 8990ではロードできない。
STQ1_0カーネルを取り込むPRが、CPU NEON側はPR #22836としてまだopen、CUDA側はPR #23505としてcloseされたまま再マージ待ち。
AngelSlim付属のフォーク済みllama.cppを別途ビルドするか、本家側のPRがマージされるのを待つかの二択になる。
440MBに収まること自体は事実だが、brew install llama.cpp した標準環境ではまず動かない。
30B-A3Bは標準ルートにまだ来ていない
tencent/Hy-MT2-30B-A3B のconfig.jsonを見ると architectures: ["HYV3ForCausalLM"]、HFタグは hy_v3。Hy-MT2世代から入った新アーキで、既存の hunyuan_v1_dense / hunyuan_v1_moe の系列とは別物。
公開されているのは元のsafetensorsとFP8版で、GGUFはまだ降りてきていない。llama.cpp側にも hy_v3 を入れるPRは見当たらなかった。
Macでローカル動作させたいなら、現状で動かせるのは1.8Bか7BのGGUFだけ。
参考にした一次情報は以下。