TransForge:ローカルのLLMを使って、変更されたページのみを翻訳する静的サイト翻訳ツール

公開日
2026年10月19日
更新日
2026年10月19日
著者
Jacob Lloyd — プロジェクト完了後、AIの支援を受けて執筆
読了時間
約12分で読めます

かんたんに言うと: TransForgeは、自分のコンピューター上で動作するAIモデルを利用してウェブサイトのページを他言語に翻訳する小さなプログラムです。そのため、単語ごとの課金もなく、翻訳会社にデータが送信されることもありません。翻訳済みの各ページの情報を記憶しているので、次回実行時には実際に変更されたページのみを再翻訳し、人間が手作業で修正した翻訳内容を上書きすることは決してありません。

このサイトは英語および他7言語に対応していますが、私自身が手動でページを翻訳したことは一度もありません。TransForgeというコマンドラインツールがそれを実行してくれます。このツールは各Markdownページを私のStudioForge GPUサーバー上で動作するモデルに送信し、結果を確認した上で page.ja.md を page.md の隣に作成します。作業がスムーズに進むのは履歴管理機能のおかげです。各ソースページおよび生成された翻訳内容のフィンガープリントが記録されるため、夜間バッチ処理では変更のあった部分のみが翻訳され、誰かが手動で修正した翻訳も決して上書きされません。

要約

  • 概要: MITライセンスの無料Python CLIツール、バージョン0.2.0。ファイルは2つだけで、標準ライブラリとPyYAMLのみが必要です。
  • 前提条件: Markdownファイルで構成された静的サイトおよびローカルのモデルサーバー。StudioForge向けに作られており、すべての処理はOpenAI互換API経由で行われるため、クラウド翻訳サービスの利用も単語単位での課金もありません。
  • 判断基準: 各ページおよび言語ごとに、翻訳が存在しないか、古くなっているか、手動で編集されたか、最新状態かをコンテンツのハッシュ値で判定します。ファイルの更新日時は一切考慮しません。
  • 行わないこと: 見出しやコードブロック、リンク、画像が失われるような翻訳を行ったり、手動編集済みの内容を上書きしたり、GPU上で実行中のベンチマーク処理を妨げたりしません。
  • インストール方法: uv tool install --python 3.13 git+https://github.com/LaserLloyd/TransForge またはリポジトリ内のDocker設定をご利用ください。

最終的に得られるもの

1つのコマンドで各言語の翻訳状況が確認できます。2026年10月19日時点でのこのサイト(英語ページ43件、7言語)の状態は以下の通りです:

$ transforge status --site laserlloyd
site laserlloyd: 43 source pages x 7 languages | model mradermacher/Hy-MT2-30B-A3B-i1-GGUF/Hy-MT2-30B-A3B.i1-Q4_K_S
  lang     missing     stale    edited untracked     drift   current
  ja             1         0        10         0         0        32
  zh             1         0         8         0         0        34
  ...
  -> 7 sibling(s) need translation

statusコマンドはモデルサーバーに一切問い合わせず、サイト情報およびマニフェストのみを読み取ります。transforge run --site laserlloydと実行すると、不足している7ページのみが翻訳されます。「edited」列はTransForgeの処理後に誰かが手動で翻訳内容を変更したページを示します。これらは私が指示しない限りそのまま維持されます。

また、単発的なモデル検証用にテキスト翻訳も可能です:

$ echo "Only the pages that changed get translated again." | transforge text --to ja
変更されたページのみ、再翻訳されます。

GPUサーバー上でモデルが既に起動済みの状態で、この処理には15秒しかかかりませんでした。

何を翻訳するかの判断基準

各ソースページおよび翻訳先言語ごとに、英語原文のハッシュ値、生成された翻訳文のハッシュ値、そして出力内容を決定する設定(モデル名、プロンプト、保護対象用語、温度パラメータなど)のハッシュ値が記録されます。これらを比較することで各ページ・言語ごとの状態が判明します:

状態 意味 runで翻訳されるか
missing 翻訳ファイルがまだ存在しない はい
stale 翻訳作成後に英語原文が変更された はい
edited 誰かが手動で翻訳内容を修正した いいえ。--forceおよび明示的な --files指定時のみ可能
untracked TransForge以外の手段で翻訳ファイルが作成されている いいえ。acceptコマンドで取り込み可能
drift 原文・翻訳文とも変更なしだがモデルやプロンプト設定が変わった いいえ。通知のみ
current 何もする必要がない いいえ

このうち「edited」と「drift」の2つが特に重要です。手動編集の方が原文変更より優先されます。両方が起きた場合でもページは「edited」状態となり、自動処理によって修正内容が失われることはありません。またモデルを変更してもサイト全体が無断で再翻訳されることはなく、「drift」として通知されるだけです。そこからどのページをやり直すかはユーザーが判断します。

翻訳実行前には構造チェックも行われます。見出し、コードブロック、表、画像、リンクの数が原文と一致していること、日本語ページでは日本語文字が実際に使われていること、保護対象ブランド用語が不適切に生成されていないこと、最低文字数要件を満たしていることなどが確認されます。いずれかが合致しない場合は既存翻訳が維持されます。内部リンクの書き換えもモデルではなくTransForgeが行います。例えば日本語ページが存在する場合に限り /projects/foo/ が /ja/projects/foo/ へ変更されます。上書き対象ファイルは事前にバックアップフォルダへコピーされます。

インストールおよび初回実行

uv tool install --python 3.13 git+https://github.com/LaserLloyd/TransForge
mkdir -p ~/.config/transforge
cat > ~/.config/transforge/config.toml <<'EOF'
[defaults]
endpoint = "http://localhost:1234"
model = "publisher/repo/file-stem"

[sites.example]
root = "~/sites/example"
content_dirs = ["content/projects", "content/pages"]
languages = ["ja", "de"]
lang_names = { ja = "Japanese", de = "German" }
link_dirs = ["projects"]
no_translate = ["MyProduct"]
translate_fields = ["title", "excerpt"]
EOF
export TRANSFORGE_LLM_API_KEY=...        # サーバー側でキーが必須の場合のみ設定
transforge config                         # 解決済み設定情報を表示。キー値は一切出力されない
transforge models                         # 利用可能なモデル一覧。フルIDを設定ファイルへ記載する
transforge run --site example --dry-run   # 翻訳対象予測の確認
transforge run --site example --limit 2   # 2ページのみ翻訳し、内容を確認

endpointには /v1 を除いたサーバールートを指定します。modelにはサーバーが提示するフルIDを記載する必要があります(StudioForgeのIDは publisher/repo/file-stem 形式です)。不明なIDを指定するとコード5で終了し、最も近い候補が表示されます。no_translateには翻訳を行わない語句、translate_fieldsには翻訳対象となるフロントマターのキー名を指定します。それ以外のキーはそのまま引き継がれます。DebianやUbuntuではシステム標準Python環境下での pip install . は禁止されています(PEP 668)。uv tool、pipx、または仮想環境をご利用ください。

既存サイトに他ツールで作成された翻訳がある場合は transforge accept --site example を1回実行します。これにより既存ファイルが「最新状態」として記録され、再翻訳対象から外れます。

終了コードはスクリプトやcron用に用意されています:0=処理完了または対象なし、1=個別ページで失敗(status出力でも未処理と表示)、2=設定エラーまたはサーバーがAPIキーを拒否、4=サーバーに接続不可、5=指定モデルがサーバー上に存在しない、6=ベンチマーク処理がGPUを占有中でジョブが保留中。

Docker版

リポジトリにはCompose設定も用意されており、サイトフォルダーに対してTransForgeをツールボックスとして実行できます。マニフェストはボリュームに保存され、必要に応じてスケジューラサービスも利用可能です:

git clone https://github.com/LaserLloyd/TransForge.git && cd TransForge
cp deploy/compose/.env.example deploy/compose/.env    # LLM_BASE_URLおよびTRANSFORGE_LLM_API_KEYを設定
docker compose -f deploy/compose/compose.yml run --rm app status --all

ポートは開放されません。コンテナ内では localhost がコンテナ自身を指すため、モデルサーバーはコンテナから到達可能なアドレスで待ち受ける必要があります。私自身はネイティブ環境でTransForgeを利用しており、コンテナ版は試用していません。詳細はリポジトリ内の docs/deploy/docker.md に記載されています(バックアップ機能も含む)。

0.2.0での新機能

2026年10月にリリースされた0.2.0では主にStudioForge 2.0サーバーとの連携強化が図られており、APIキーの利用が必須となりました:

  • APIキー対応 TransForgeはすべてのリクエストで Authorization: Bearer を送信します。キーは TRANSFORGE_LLM_API_KEY(または STUDIOFORGE_API_KEY、api_key_envで指定した変数)から取得されます。キーのローテーションによりページが「古くなった」状態になることはありません。キーが不要なサーバーでは1行の応答とコード2が返されます(下記参照)。
  • ベンチマーク保護機能 翻訳前にGPUを占有しているベンチマーク処理の有無を確認し、存在する場合は処理を中断します。以前はリース取得失敗時を「何も実行中でない」と誤判定して保護機能が無効化されるケースがありましたが、現在はコード2で停止します。
  • Windows対応 各OSで / 区切りが使われるようになったため、Windows・Linux・コンテナ間でもマニフェストの互換性が確保されました。既存のWindows用マニフェストは読み込み時に自動的に再キー付けされます。accept --all で「再構築」を試みると古い翻訳が最新状態と誤認されるため推奨されません。
  • 管理用PINの廃止 モデルのロード・アンロードはAPIキーのみで行うようになりました。PINはあと1回のリリースまで利用可能ですが、唯一の認証手段の場合には警告メッセージが出力されます。
rig returned HTTP 401 Unauthorized for http://<server>:1234/api/status -- StudioForge requires credentials: set $TRANSFORGE_LLM_API_KEY (or `api_key_env` / `api_key` in the config)

アップグレード方法:uv tool install --reinstall --python 3.13 git+https://github.com/LaserLloyd/TransForge を実行後、キー必須のサーバーであれば TRANSFORGE_LLM_API_KEY を設定してください。

注意点

  • 最初の数ページは必ず目視確認を 構造チェックでは不整合は検出できても語句の誤りまでは判別できません。私は専用翻訳モデルであるHy-MT2 30Bを prompt_template = "hunyuan-mt" 設定で利用しています。汎用インストラクトモデルでもデフォルトテンプレートで問題ありませんが、重要なコンテンツは必ず人間の目で確認すべきです。
  • 手動編集済み翻訳は凍結状態 意図した仕様ですが、原文修正がその言語に反映されなくなります。status -v で該当ページを一覧でき、run --force --files <page> で意図的に再翻訳も可能です。
  • モデル変更=全ページ再翻訳ではない 「drift」状態として表示されるだけです。必要なページのみ --force --files 指定で再処理してください。
  • StudioForge向け設計 モデルの並列スロット準備やベンチマーク確認はStudioForge専用API経由で行われます。READMEではllama.cppサーバーでも翻訳可能と記載されていますが、私はStudioForge環境でのみ検証しています。
  • 再帰処理不可 content_dirs に指定したディレクトリの1階層下のみスキャンします。ページを含むフォルダーは個別に列挙する必要があります。
  • 英語固定ページの設定 フロントマターで en_only: true(または translate: false)を指定すると、そのページは完全にスキップされます。

入手方法

github.com/LaserLloyd/TransForge より入手可能。MITライセンスです。READMEにはWindows・Linux・macOS向けのインストール手順、設定項目の詳細、さらにホステッドモデルを利用した二次検証機能(初期状態では無効)も記載されています。翻訳処理自体は常にローカル環境で実行されます。

関連記事: StudioForge(モデルが動作するGPUサーバー)、ローカルAIエージェントボックスによるサイト管理、LLMを活用したプロジェクトのシステム適応方法。


← AIとローカルLLMをもっと見る