1. Phi-3 Mini とは? — 小型SLMの実力

Phi-3 Mini は Microsoft が 2024 年に公開した Small Language Model (SLM) です。パラメータ数は 3.8 億(3.8B) と GPT-4 系の 1/100 以下でありながら、多くのベンチマークで同規模または大規模モデルに匹敵する精度を達成しています。

なぜ翻訳エージェントに向いているのか?

  • 日英翻訳の精度が高い — 高品質な英語テキストで重点的に学習しているため、英語⇔日本語の変換品質が安定している
  • 指示追従性(Instruction Following)が優秀 — 「日本語に翻訳してください」といったシンプルな指示を忠実に実行できる
  • 低スペックPC でも動作 — INT4 量子化 ONNX モデルなら CPU のみで推論可能(Core i7 程度で快適)
  • 完全ローカル動作 — データが外部に送信されないためプライバシー・セキュリティ面でも安心

💡 SLM vs LLM:Large Language Model(LLM)が数十〜数百B のパラメータを持つのに対し、Small Language Model(SLM)は数B 以下。用途を絞ることで小さくても高性能を実現する次世代のアーキテクチャトレンドです。

2. 事前準備と必要なもの

ツール / 環境 バージョン 備考
.NET SDK 8.0 以上 dotnet.microsoft.com から取得
Visual Studio / VS Code 最新版推奨 CLI のみでも動作
Hugging Face CLI(任意) 任意 モデルダウンロードを簡略化
RAM 8GB 以上 16GB 推奨
ストレージ 3GB 以上の空き INT4 モデル約 2.3GB

3. モデルのダウンロード

Hugging Face から公式の ONNX 量子化モデルを取得します。CPU 推論 (INT4) バリアントを使用します。

方法 A:Git LFS で丸ごとクローン

# Git LFS のインストール(初回のみ)
git lfs install

# モデルをクローン(CPU INT4 版)
git clone https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-onnx

# 使用するフォルダを確認
ls Phi-3-mini-4k-instruct-onnx/cpu_and_mobile/cpu-int4-rtn-block-32

方法 B:Hugging Face CLI(高速)

pip install huggingface_hub

huggingface-cli download microsoft/Phi-3-mini-4k-instruct-onnx \
  --include "cpu_and_mobile/cpu-int4-rtn-block-32/*" \
  --local-dir ./phi3-model
⚠️ ダウンロード後のフォルダパスを控えておいてください。後ほど C# コードの modelPath に指定します。
例:C:\Models\phi3-model\cpu_and_mobile\cpu-int4-rtn-block-32

4. プロジェクト作成 & NuGet インストール

# コンソールアプリ作成
dotnet new console -n Phi3Translator
cd Phi3Translator

# OnnxRuntimeGenAI(CPU ビルド)を追加
dotnet add package Microsoft.ML.OnnxRuntimeGenAI --version 0.6.0

# ※GPU(DirectML)を使う場合はこちら
# dotnet add package Microsoft.ML.OnnxRuntimeGenAI.DirectML --version 0.6.0
Microsoft.ML.OnnxRuntimeGenAI は ONNX Runtime の生成 AI 拡張ライブラリです。ストリーミング推論・トークナイザ・サンプリングが C# から直接使えます。

5. C# 翻訳エージェント — 最小コード

Program.cs を以下のコードで完全に置き換えてください。

📄 Program.cs C# 12 / .NET 8
using Microsoft.ML.OnnxRuntimeGenAI;

// ============================================================
//  モデルフォルダへのパスを環境に合わせて書き換えてください
// ============================================================
const string ModelPath =
    @"C:\Models\phi3-model\cpu_and_mobile\cpu-int4-rtn-block-32";

Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.WriteLine("=== Phi-3 翻訳エージェント ===");
Console.WriteLine("'exit' で終了\n");

// モデルとトークナイザを初期化(初回は数秒かかります)
using var model     = new Model(ModelPath);
using var tokenizer  = new Tokenizer(model);

while (true)
{
    Console.Write("翻訳する文章を入力 ▶ ");
    var input = Console.ReadLine()?.Trim();

    if (string.IsNullOrWhiteSpace(input)) continue;
    if (input.ToLower() == "exit") break;

    // 翻訳方向を自動判定(英語が多ければ日本語へ、それ以外は英語へ)
    bool isEnglish = input.All(c =>
        c < 128 || char.IsWhiteSpace(c) || char.IsPunctuation(c));
    string direction = isEnglish
        ? "Translate the following English text into natural Japanese."
        : "Translate the following Japanese text into natural English.";

    // Phi-3 の ChatML フォーマットでプロンプトを組み立てる
    string prompt =
        $"<|system|>\n{direction}<|end|>\n" +
        $"<|user|>\n{input}<|end|>\n" +
        "<|assistant|>\n";

    // トークナイズ
    using var tokens = tokenizer.Encode(prompt);

    // 生成パラメータ
    var genParams = new GeneratorParams(model);
    genParams.SetSearchOption("max_length",  512);
    genParams.SetSearchOption("temperature", 0.3);  // 翻訳は低めに
    genParams.SetSearchOption("top_p",       0.9);
    genParams.SetInputSequences(tokens);

    // ストリーミング生成 & 出力
    Console.Write("\n翻訳結果 ▶ ");
    using var generator = new Generator(model, genParams);
    using var tokenDec  = tokenizer.CreateStream();

    while (!generator.IsDone())
    {
        generator.ComputeLogits();
        generator.GenerateNextToken();
        var token = generator.GetSequence(0)[^1];
        var word  = tokenDec.Decode(token);
        Console.Write(word);  // トークンごとにリアルタイム表示
    }
    Console.WriteLine("\n");
}

コードのポイント解説

🔤 ChatML フォーマット

Phi-3 は <|system|><|user|><|assistant|> の特殊トークンで会話を区切ります。このフォーマットを守ることで指示追従精度が大幅に向上します。

🌊 ストリーミング出力

TokenizerStream を使って 1 トークンずつリアルタイム表示します。全生成完了を待たずに結果が見えるため UX が向上します。

🌡️ temperature=0.3

翻訳タスクでは創造性より正確性が重要。低い temperature 値で決定論的・安定した出力を得ます。(0〜1 の範囲で調整)

🔍 自動言語判定

ASCII 文字のみかどうかで英語/日本語を簡易判定し、プロンプトの翻訳方向を動的に切り替えます。

6. 実行と動作確認

dotnet run

起動後、以下のような対話が可能になります:

=== Phi-3 翻訳エージェント ===
‘exit’ で終了

翻訳する文章を入力 ▶ Artificial intelligence is transforming every industry.
翻訳結果 ▶ 人工知能はあらゆる産業を変革しつつあります。

翻訳する文章を入力 ▶ 本日は晴天なり。
翻訳結果 ▶ It is a clear, beautiful day today.

翻訳する文章を入力 ▶ exit

よくあるエラーと対処法

エラー 原因と対処
DirectoryNotFoundException ModelPath が間違っている。genai_config.json があるフォルダを指定
OutOfMemoryException RAM 不足。他のアプリを閉じるか 16GB RAM 機を使用
生成が止まらない max_length を小さくする(例:256)
文字化け Console.OutputEncoding = UTF8 が設定されているか確認

7. カスタマイズ Tips

🌐 GPU 対応(DirectML)

Windows GPU(AMD/Intel/NVIDIA)を使う場合は NuGet パッケージを変更し、GPU 用モデルフォルダを指定:

dotnet add package Microsoft.ML.OnnxRuntimeGenAI.DirectML
# モデルパス: /directml/directml-int4-awq-block-128

🧩 Web API 化(ASP.NET Core)

翻訳エージェントをサービスとして公開するには Program.cs の翻訳ロジックを DI サービスに分離し、Minimal API のエンドポイントから呼ぶだけです:

app.MapPost("/translate", async (TranslationService svc, TranslateRequest req)
    => Results.Ok(await svc.TranslateAsync(req.Text)));

📄 翻訳対象を増やす(多言語)

System プロンプトの言語指示を変えるだけで多言語に対応可能です:

// 中国語への翻訳
string direction = "Translate the following text into Simplified Chinese.";

まとめ

  • Phi-3 Mini 4K は 3.8B の小型モデルながら、翻訳タスクに十分な性能を持つ
  • Microsoft.ML.OnnxRuntimeGenAI により、C# から 数十行でローカル LLM を呼び出せる
  • ChatML フォーマット + 低 temperature で安定した翻訳品質を実現
  • CPU のみ・クラウド不要で完全ローカル動作するため、プライバシー要件の厳しい業務にも対応可能
  • DirectML / ASP.NET Core への拡張も容易