麻布技術研究所

Open-weight LLM

8ドルで最新フロンティアモデルKimi K3を動かす

2.8兆パラメータのKimi K3を量子化GGUFとHugging Face Jobsで動かした。8枚のH200、約5,000字の日本語推論を17.2 token/秒で完結させ、実行時間10分34秒、推定7.33〜8.00ドルに収めた方法を紹介する。

Research Note

Kimi K3は、Moonshot AIが公開した2.8兆パラメータのフロンティア級オープンウェイトモデルです。 Hugging Faceからmodelを取得でき、OpenRouterからAPIとして呼び出すこともできます。

誰でもdownloadできるなら、実際に動かしてみたくなる。 それがエンジニアの習性です。

しかし、2.8兆パラメータのmodelに必要なGPUをオンプレミスで揃えるのは容易ではありません。 そこで今回は、Hugging Face Jobsで必要な時間だけ8枚のH200を借りて推論しました。

Hugging Face Jobsは、Hugging Faceが提供するクラウドコンピュート環境で、Docker imageとcommandを指定して一回限りのbatch処理を実行するサービスです。 今回は8基のH200を選び、量子化したKimi K3を載せました。

少し前なら、この規模のモデルを自分たちで動かす実験は、研究所か巨大テック企業の仕事でした。 便利な世の中になりましたね。

結論は、約8ドルでKimi K3を8枚のH200へ載せ、ラッセルの記述理論について約5,000字の日本語推論を最後まで完結させられました。 download開始からJob終了までの時間は10分34秒、生成速度は17.2 token/秒です。

[ Prompt: 74.9 t/s | Generation: 17.2 t/s ]

Kimi K3とは何か

Kimi K3は、Moonshot AIが公開したMixture-of-Experts型のオープンウェイト大規模言語モデルです。

総パラメータ数は約2.8兆ですが、1 tokenの計算で有効になるのは約1040億です。 896個のrouted expertから16個を選び、すべてのパラメータを毎回計算するより演算量を抑えています。

ただし、1040億パラメータのmodelと同じmemoryで動くわけではありません。 入力によって選ばれるexpertが変わるため、推論環境は896個すべての重みへアクセスできる必要があります。

計算する重みは一部でも、保管する重みは全体です。

さらに、Kimi K3はKimi Delta AttentionやAttention Residualsなどの独自構造を含みます。 model fileを用意するだけでは動かず、推論runtime側の対応も必要です。

8枚のH200にも公式checkpointは載らない

今回使ったHugging Face Jobsのh200x8は、H200を8基、合計1,128 GBのGPU memoryを持ちます。 二進表記では約1,050.5 GiBです。

一方、Kimi K3の公式checkpointは1,560,860,324,864 bytesです。 約1.56 TB、約1,453.7 GiBあります。

重みだけで、8枚のH200のGPU memoryを約403 GiB超えます。 KV cache、内部state、通信bufferを置く前に容量不足です。

公式checkpointも単純なFP16ではなく、quantization-aware trainingを経たMXFP4重みです。 それでも載りません。

そこで、さらに強く量子化されたQ2_Kを使いました。

量子化は巨大モデルをリーズナブルなGPUへ載せる

ここで使う量子化とは、modelの重みを少ないbit数で表現し、memory使用量と読み出し量を減らす処理です。

今回選んだGrEarl/Kimi-K3-GGUFのQ2_Kは864.81 GiBです。 公式checkpointの約1,453.7 GiBから、およそ6割の大きさまで縮んでいます。

重み 公開サイズ h200x8への搭載
公式checkpoint 約1,453.7 GiB NG
Q2_K GGUF 864.81 GiB 容量上はOK

Q2_KのQ2は、すべての値を一律2 bitで保存するという意味ではありません。 重みをblock単位で量子化し、一部のtensorには異なる精度を使います。 このmodelの実効値は2.673 bits per weightです。

量子化による容量圧縮のトレードオフは品質です。 bit数を減らせば元の重みとの誤差が増え、回答品質が低下する可能性があります。

したがって、今回の構成でmodelが回答したことと、公式モデルの能力を維持していることにはなりません。 もしこの構成で本番導入する場合は、対象業務のデータで品質を測る必要があります。

GGUFは量子化方式ではない

量子化と一緒に出てくるのがGGUFです。

GGUFは、GGMLとその実行系で推論するmodelを保存するためのbinary file形式です。 公式仕様では、高速なloadと保存、拡張性、mmapとの互換性を意図した形式と説明されています。

GGUFにはtensorだけでなく、architecture、context length、tokenizer、量子化方式など、runtimeが必要とするmetadataも入ります。

GGUFと量子化は同じものではありません。

  • GGUF:tensorとmetadataを収めるfile形式。
  • 量子化:tensorの数値を少ないbit数で表現する変換。

GGUFにはF16の重みも量子化済みの重みも入れられます。 「GGUFだから小さい」のではなく、「量子化した重みをGGUFへ格納したから小さい」が正確です。

今回のQ2_Kは、94個のGGUF shardへ分割されています。 llama.cppのsplit仕様に従い、先頭のKimi-K3-Q2_K-00001-of-00094.ggufを指定すると、runtimeが残りの93 fileを見つけます。

Hugging Face Jobsが嬉しい場面

Hugging Face Jobsは、Docker image、command、hardware flavorを指定し、Hugging Faceの計算基盤で処理を一回実行する仕組みです。

常駐APIを公開せず、hf jobs runからGPUを確保し、logを受け取り、commandの終了まで待てます。 料金はhardwareの利用時間に応じて発生します。

今回のh200x8は、Hugging Faceの料金表で40 USD / hrです。 --timeout 2hを指定したため、hardware料金の上限は80ドルになります。

80ドルは、短い回答の料金として見れば高価です。 しかし、H200を8枚所有し、driver、CUDA、scheduler、network、storageを整備する費用と比べれば、大規模modelの成立条件を確認するための小さな予算です。

Jobsは、次のような場面で特に効きます。

  • 数百GBのmodelを一度だけloadし、起動できるか判定する。
  • 顧客ごとに異なるGPU構成で、同じ検証commandを再実行する。
  • 量子化方式と推論runtimeの組み合わせを比較する。
  • 実験ごとの時間と費用を記録する。
  • 常駐serverを作る前の検証。

今回試したこと

単純な知識問題では、2.8兆パラメータのmodelを使う意味が見えません。 そこで、確定記述、存在、一意性、否定のscopeを区別しなければ答えられない長文課題を与えました。

筆者の大好きな思考実験であるラッセルの記述理論で扱われる「現在のフランス国王の頭は禿頭か?」という問いです。

Kimi K3には、次の処理を一つの回答で実行させました。

  1. 元の問いを一階述語論理へ変換する。
  2. 同じ論理構造を持つ現代的な問いを自作する。
  3. 自作した問いへKimi K3自身が回答する。
  4. Russell、Strawson、自由論理の扱いを区別する。
  5. 自分の論証に対する反論を作り、回答する。
  6. 5つの条件で同型性を自己検証する。
  7. 一般読者向けの一文で締める。

出力は3,500字以上5,500字以内と指定しました。 生成枠は8,192 token、contextは16,384 tokenです。

実行時間を短くする5つのテクニック

巨大modelのJobでは、token生成以外の時間が大きくなります。 compile、download、load、終了処理を放置すると、回答を作っていない時間にも8枚のH200の料金が発生します。

今回は、次の5つを実施しました。

1.runtimeを事前buildする

Kimi K3対応のllama.cpp forkを、public Docker Spaceで事前にbuildしました。

nyasukun/kimi-k3-llama-cpp-runtime

Dockerfileはmulti-stage buildです。 CUDA 12.8.1のdevel imageでcommit固定のllama-cliを作り、実行に必要なbinaryとshared libraryだけをruntime imageへ移しています。

JobsはSpaceのimageをhf.co/spaces/nyasukun/kimi-k3-llama-cpp-runtimeとして直接起動します。 H200を確保した後にapt installやCMake buildをする時間はありません。

2.量子化済みmodelを選ぶ

Q2_Kは、公式checkpointより約589 GiB小さい864.81 GiBです。

量子化の第一目的は8枚のH200へ載せることです。 同時に、networkで取得するbytesとstorageから読むbytesも減るため、cold start短縮にも効きます。

3.Xetで94 shardをlocal diskへ並列downloadする

model repositoryを遅延mountせず、Jobの冒頭でhf downloadを実行しました。

export HF_XET_HIGH_PERFORMANCE=1

hf download GrEarl/Kimi-K3-GGUF \
  --revision 28d2a4ad986f4a487dfe24a22504a357560abfc4 \
  --include 'Kimi-K3-Q2_K-*.gguf' \
  --local-dir /local-model \
  --max-workers 32

Hugging Face HubのXet設定にあるHF_XET_HIGH_PERFORMANCE=1を有効にし、CPU、memory、networkを積極的に使わせます。

h200x8には184 vCPU、2 TBのmemory、24 TBの一時diskがあります。 94 shardを32 workerでlocal diskへ取得し、download後のmodel loadはlocal pathから行いました。

4.推論をGPUへ載せ、serverを起動しない

--n-gpu-layers allですべてのlayerをGPUへ載せ、--split-mode layerで8枚へ分割しました。 CPU offloadを避け、GPUとCPU memoryの間をtokenごとに往復させません。

一回の回答だけが目的なので、llama-serverは起動しません。 port公開、health check、request待ちを持たないllama-cliのsingle-turn実行です。

5.回答とTPSを得たらcleanupを待たない

回答と次のtiming行がlogへ出た時点で、Jobの目的は達成しています。

[ Prompt: 74.9 t/s | Generation: 17.2 t/s ]

shellはtiming行を監視し、結果を確認したらllama-cliSIGKILLを送ります。 数百GiBのmodel、CUDA context、multi-GPU resourceを順番に解放する処理を待ちません。

これは使い捨てcontainer内のread-only推論だから選べる方法です。 学習checkpoint、書き込み途中のartifact、常駐serverへ適用するとdataを壊す可能性があります。

今回のlogではKILL_SIGNAL_SENT=1LLAMA_CLI_EXIT=137になりました。 親shellは回答とTPSの取得を成功条件として0で終了し、Job全体はCompletedになっています。

実行command

次のcommandをそのまま実行しました。 事前にhf auth loginを済ませ、Jobsを利用できるcreditとHF_TOKEN secretを用意しています。

set -euo pipefail

JOB_NAME="kimi-k3-russell-8k-$(date -u +%Y%m%dT%H%M%SZ)"
RUNTIME_IMAGE='hf.co/spaces/nyasukun/kimi-k3-llama-cpp-runtime'
MODEL_REPO='GrEarl/Kimi-K3-GGUF'
MODEL_REVISION='28d2a4ad986f4a487dfe24a22504a357560abfc4'
KIMI_PROMPT='次の課題へ、日本語で3,500字以上5,500字以内の、検証可能な論証として回答してください。出発点は、バートランド・ラッセルの記述理論で扱われる「現在のフランス国王の頭は禿頭か?」という問いです。最初に、一般読者向けの結論を一文で示してください。次に、この問いの難しさが禿頭という性質ではなく、「現在のフランス国王」という確定記述が、対象の存在と一意性を暗黙に要求している点にあることを説明してください。続いて、問いの論理的な骨格を、対象x、確定記述を構成する条件F、述語Gを用いて抽出してください。存在、一意性、述語の帰属を含む肯定文、文全体を否定するwide-scope negation、記述対象へ反対の述語を帰属させるnarrow-scope negationを、それぞれ一階述語論理の式として導出してください。その後、王、国家、禿頭という語を使わず、現代のAI、分散システム、企業統治、宇宙開発、またはデジタル社会を題材に、元の問いと同じ論理構造を持つ新しい質問を一つ自分で考案してください。単なる言い換えではなく、確定記述が存在と一意性を暗黙に要求する一方、与えられた前提から該当対象が存在しないと論理的に確認できる設定にしてください。現実世界の不確かな最新情報には依存しないでください。作成した質問を明示した後、元の問いと新しい問いを別々に論理式へ変換し、両者がどの対応関係によって同型なのかを示してください。続いて、作成した質問をKimi K3自身への問いとして提示し、Kimi K3として回答してください。日常会話として誤解の少ない答え、ラッセルの記述理論による厳密な答え、wide-scopeとnarrow-scopeで否定の真理値が変わる理由、前提失敗として扱うストローソン的立場、自由論理を採用した場合の扱いを区別してください。「存在しないから質問は無意味」で終わらせず、なぜ肯定文が偽になり、どの否定が真になり得るのかを段階的に論証してください。自由論理にはnegative、positive、neutralなど複数の体系があるため、一つの扱いだけが唯一の結論であるかのように一般化しないでください。さらに、自分の分析に対する最も強い反論を一つ作り、その反論へ回答してください。最後に、作成した質問が元の問いと同じ構造を持つかを、存在要求、一意性要求、述語帰属、記述対象の不存在、否定のscopeという5項目のchecklistで自己検証し、一般読者へ返す一文の最終回答で必ず締めてください。見出しを付け、論理式と自然言語の対応が追えるように書いてください。出力枠が不足しそうな場合は、自由論理と反論の説明を短縮してください。5項目の自己検証と最後の一文は省略しないでください。'

printf 'job_name=%s\n' "$JOB_NAME"

hf jobs run \
  --name "$JOB_NAME" \
  --flavor h200x8 \
  --timeout 2h \
  --secrets HF_TOKEN \
  -e "MODEL_REPO=$MODEL_REPO" \
  -e "MODEL_REVISION=$MODEL_REVISION" \
  -e "KIMI_PROMPT=$KIMI_PROMPT" \
  -e HF_XET_HIGH_PERFORMANCE=1 \
  "$RUNTIME_IMAGE" \
  -- \
  bash -lc '
    set -euo pipefail

    MODEL_DIR=/local-model
    MODEL_PATH="$MODEL_DIR/Kimi-K3-Q2_K-00001-of-00094.gguf"
    CLI_LOG=/tmp/kimi-k3-cli.log

    mkdir -p "$MODEL_DIR"

    printf "MODEL_DOWNLOAD_START=%s\n" "$(date -u +%FT%TZ)"
    DOWNLOAD_STARTED=$(date +%s)

    hf download "$MODEL_REPO" \
      --revision "$MODEL_REVISION" \
      --include "Kimi-K3-Q2_K-*.gguf" \
      --local-dir "$MODEL_DIR" \
      --max-workers 32

    DOWNLOAD_FINISHED=$(date +%s)

    shopt -s nullglob
    GGUF_SHARDS=("$MODEL_DIR"/Kimi-K3-Q2_K-*.gguf)
    SHARD_COUNT=${#GGUF_SHARDS[@]}

    test "$SHARD_COUNT" -eq 94
    test -s "$MODEL_PATH"

    printf "model_download_seconds=%s\n" \
      "$((DOWNLOAD_FINISHED - DOWNLOAD_STARTED))"
    printf "gguf_shards=%s\n" "$SHARD_COUNT"
    printf "INFERENCE_START=%s\n" "$(date -u +%FT%TZ)"
    printf "PROMPT_TEXT=%s\n" "$KIMI_PROMPT"

    : > "$CLI_LOG"

    stdbuf -oL -eL /app/llama-cli \
      --model "$MODEL_PATH" \
      --split-mode layer \
      --n-gpu-layers all \
      --ctx-size 16384 \
      --jinja \
      --chat-template-kwargs "{\"thinking_effort\":\"high\"}" \
      --single-turn \
      --simple-io \
      --no-display-prompt \
      --color off \
      --show-timings \
      --n-predict 8192 \
      --seed 42 \
      --temperature 1.0 \
      --top-p 0.95 \
      --top-k 0 \
      --min-p 0.0 \
      --prompt "$KIMI_PROMPT" \
      > "$CLI_LOG" 2>&1 &

    CLI_PID=$!

    tail -n +1 -F "$CLI_LOG" &
    TAIL_PID=$!

    stop_tail() {
      kill "$TAIL_PID" 2>/dev/null || true
      wait "$TAIL_PID" 2>/dev/null || true
    }

    process_state() {
      if [ -r "/proc/$CLI_PID/stat" ]; then
        awk "{print \$3}" "/proc/$CLI_PID/stat"
      else
        printf "X\n"
      fi
    }

    trap stop_tail EXIT

    RESULT_CAPTURED=0

    while kill -0 "$CLI_PID" 2>/dev/null; do
      if grep -Eq \
        "\[ Prompt: [0-9.]+ t/s \| Generation: [0-9.]+ t/s \]" \
        "$CLI_LOG"; then
        RESULT_CAPTURED=1
        break
      fi
      sleep 1
    done

    if grep -Eq \
      "\[ Prompt: [0-9.]+ t/s \| Generation: [0-9.]+ t/s \]" \
      "$CLI_LOG"; then
      RESULT_CAPTURED=1
    fi

    if [ "$RESULT_CAPTURED" -eq 1 ]; then
      KILL_SIGNAL_SENT=0
      CLI_STATE=$(process_state)

      if kill -0 "$CLI_PID" 2>/dev/null \
        && [ "$CLI_STATE" != "Z" ]; then
        if kill -KILL "$CLI_PID" 2>/dev/null; then
          KILL_SIGNAL_SENT=1
        fi
      fi

      set +e
      wait "$CLI_PID"
      CLI_EXIT=$?
      set -e

      sleep 2
      stop_tail
      trap - EXIT

      grep -E \
        "\[ Prompt: [0-9.]+ t/s \| Generation: [0-9.]+ t/s \]" \
        "$CLI_LOG" | tail -n 1

      printf "RESULT_CAPTURED=1\n"
      printf "KILL_SIGNAL_SENT=%s\n" "$KILL_SIGNAL_SENT"
      printf "LLAMA_CLI_EXIT=%s\n" "$CLI_EXIT"
      printf "JOB_PROCESS_END=%s\n" "$(date -u +%FT%TZ)"
      exit 0
    fi

    set +e
    wait "$CLI_PID"
    CLI_EXIT=$?
    set -e

    stop_tail
    trap - EXIT

    printf "RESULT_CAPTURED=0\n" >&2
    printf "LLAMA_CLI_EXIT=%s\n" "$CLI_EXIT" >&2
    exit 1
  ' 2>&1 | tee kimi-k3-russell-8k.log

実行結果

主要なlogは次のとおりです。

MODEL_DOWNLOAD_START=2026-08-02T05:31:01Z
model_download_seconds=204
gguf_shards=94
INFERENCE_START=2026-08-02T05:34:25Z

[ Prompt: 74.9 t/s | Generation: 17.2 t/s ]

RESULT_CAPTURED=1
KILL_SIGNAL_SENT=1
LLAMA_CLI_EXIT=137
JOB_PROCESS_END=2026-08-02T05:41:35Z

時間を分解すると、次のようになります。

区間 時間 含まれる処理
model download 3分24秒 約927 GB、94 shardの取得
download完了後 7分10秒 model load、prompt処理、長文生成、終了制御
logで確認できるprocess全体 10分34秒 download開始から親shell終了まで

約927 GBを204秒で取得したため、単純平均は約4.54 GB/秒です。

Hugging Faceの画面に出るJob started at 2026-08-02 05:29:49は、Jobがscheduleされた時刻です。 GPU上でapplicationが処理を始めた時刻とは限らないため、10分34秒の計算には使っていません。

費用は約7.33〜8.00ドル

40ドル/時を10分34秒へ比例配分すると、7.04ドルです。 Hugging Face Jobsは分単位課金なので、11分として約7.33ドルになります。

scheduleされた05:29:49からprocess終了の05:41:35までは11分46秒です。 この全区間が課金対象だったと仮定し、12分へ丸めると8.00ドルです。

Kimi K3が自作した問い

Kimi K3は、元の問いの難しさを「禿頭」という述語ではなく、確定記述が要求する存在と一意性に置きました。 Stanford Encyclopedia of PhilosophyのRussell解説で示される分析と一致します。

modelが自作したのは、分散systemの書込みプライマリを使う問いでした。

保守window中はすべての書込みleaseが失効し、現在のlease tableは空である。

この前提から、次の問いを作っています。

「サービスSの現在の唯一の書込みプライマリは、クライアント書込みを受理しているか?」

F(x)を「xは有効な書込みleaseを保持する」、G(x)を「xはclient書込みを受理する」とした肯定文は、次の式になります。

∃x(F(x) ∧ ∀y(F(y) → y = x) ∧ G(x))

lease tableが空なので、この肯定文は偽です。 Kimi K3は、否定のscopeを二つに分けました。

wide-scope  : ¬∃x(F(x) ∧ ∀y(F(y) → y = x) ∧ G(x))
narrow-scope:  ∃x(F(x) ∧ ∀y(F(y) → y = x) ∧ ¬G(x))

文全体を否定するwide-scopeは真です。 一方、「唯一のプライマリは存在するが、書込みを受理しない」と読むnarrow-scopeは、存在要求が満たされないため偽になります。

Kimi K3は、一般読者向けの結論を次の一文で締めました。

「現在のフランス国王は禿頭か?」も考案したプライマリの問いも、答えは「その一意対象は前提上存在しないので、肯定は偽、文全体の否定は真、しかし“その対象が反対状態だ”という内側否定は真にならない」が、ラッセル流に誤解の少ない結論です。

指定した3,500字以上5,500字以内に対し、logから抽出した回答は約4,981字でした。 結論、論理式、新しい問い、理論比較、反論、五項目の自己検証、最終回答まで完結しています。

返答の感想

論証の中心は正確に見えました。

確定記述を名前として扱わず、存在、一意性、述語帰属の連言へ展開しています。 肯定、wide-scopeの否定、narrow-scopeの否定で真理値が変わる理由も追えます。 否定に関するStanford Encyclopedia of Philosophyの解説に掲載された式と対応します。

自作した問いも、元の問いと同じ構造を持っています。 対象が存在しないことを最新情報に頼らず、問題文の前提だけで確定させたため、存在失敗と否定のscopeをそのまま比較できます。

反論も表面的ではありません。 「監査log外に暗黙のプライマリがいる可能性を排除できない」という反論を作り、現実の観測問題と、問題文が定めた公理系内の導出を区別して答えました。

自由論理についてnegative、positive、neutralの違いを分けた点も改善されています。 ただし、この部分には論理形式の切替が暗黙に残っています。

Russell流のA_Sを存在量化を含む式として固定したままなら、∃xF(x)が偽である以上、positive free logicでもA_S全体は偽です。 体系によって結果が変わる議論をするには、確定記述をιxF(x)のような単称項として扱う別の形式へ切り替える必要があります。 Kimi K3はiota項へ触れましたが、この切替を明示していません。

流暢で長い回答でも、専門的な境界では前提となる形式体系が一段抜ける。 この癖まで見えたことが、今回のpromptを選んだ価値です。

8枚のH200でも17.2 token/秒になる理由

8枚のH200が、単一tokenを8倍速で作るわけではありません。

今回の--split-mode layerは、各GPUへ連続したlayer群を持たせるpipeline parallelismです。 llama.cppのmulti-GPU説明にあるとおり、layer splitは巨大modelを複数GPUのmemoryへ載せる用途に適していますが、単一sequenceのtokenはlayerを順番に通ります。

今回の8枚は、まず865 GiBの重みをGPU memoryへ載せるために必要でした。 capacityを増やす効果と、decode latencyを短縮する効果は同じではありません。

さらにKimi K3はMoEです。 1 tokenで選ぶexpertは一部でも、routingされた重みを読み、Q2_Kから計算可能な表現へ展開し、GPUをまたいで次のlayerへ渡します。

memory bandwidth、量子化kernel、GPU間通信、Kimi K3対応forkの成熟度がbottleneck候補です。

「GGUFはscaleしない」という説明を聞くことがありますが、少し雑です。 GGUFはfile形式なので、multi-GPU性能を直接決めません。 scaleを決めるのは、runtimeが量子化tensorをどう分割し、どのkernelで計算し、GPU間をどう同期するかです。

どの要因が支配的かを断定するには、GPUごとのutilization、HBM bandwidth、NVLink traffic、kernel時間が必要です。 今回確定したのは、この構成のsingle-stream Generationが17.2 token/秒だったことです。

たった10ドルの予算枠で得られたもの

用意した上限は10ドルでした。 実際の推定額は約7.33〜8.00ドルです。

その金額で、次の事実を確認できました。

  • 公式checkpointは8枚のH200にも載らない。
  • Q2_K GGUFなら容量内に収まる。
  • 約927 GBを204秒でdownloadできる。
  • 2.8兆パラメータのmodelが約5,000字の日本語論証を完結できる。
  • single-streamの生成速度は17.2 token/秒である。
  • 回答とTPSの取得後にcleanupを待たず、Jobを終了できる。

大規模modelの検証費用は、必ずしも数百万円から始まりません。 compile、download、load、generation、cleanupを分け、必要な区間だけ高価なGPUを使えば、一回の技術検証を一桁ドル台へ収められます。

オープンウェイトLLMを顧客環境へ持ち込む

今回のように、まずmodelの能力を安く確かめるだけなら、OpenRouterがおすすめです。 modelを自分でdownloadせず、APIとして呼び出した分だけ支払えます。

一方、検証の先にある顧客環境への導入では、料金だけでない条件が出てきます。 私たちは、そうした条件に合わせてオープンウェイトLLMのmodel選定から導入まで支援しています。

顧客環境では、「一番大きなmodel」を置けば終わりではありません。 dataを外へ出せるか、何秒で返す必要があるか、GPUを何枚置けるか、月額をいくらに抑えるかを先に決めます。

そのうえで、通常のAPI利用では満たしにくい要件がある場合に、modelを顧客環境へ持ち込みます。

  • プライバシー:顧客dataやpromptを外部APIへ送らず、顧客のnetwork内で推論する。
  • logits取得:各tokenの確率分布へ変換する前のlogitsを取得し、確信度、候補token、拒否判断、出力の不確実性を分析する。
  • ベクトル挿入:embeddingや中間activationへ業務固有のベクトルを挿入し、特定の知識や振る舞いを追加する。
  • モデルの書き換え:weight、adapter、sampling、runtime kernelを顧客の要件に合わせて変更する。

これらの要件では、APIの単価だけでなく、modelの内側へどこまで手を入れられるかが選定基準になります。 OpenRouterが「安く早く能力を使う」ための入口だとすれば、顧客環境への導入は「modelの挙動を理解し、制御し、業務へ組み込む」ための選択です。

その条件から、model、量子化方式、runtime、hardwareを組み合わせます。 RAG、tool call、認証、監視、更新手順、障害時の復旧まで含め、運用できる形へ落とします。

Kimi K3のようなmodelでは、file形式を一つ選ぶだけで、品質、容量、network、CUDA kernel、GPU間通信、費用が連動します。 未mergeの実装を読み、logの最後の一行から次の設計を決める場面もあります。

既存APIを呼ぶだけでは届かない場所です。 だからこそ、エンジニアリングとして面白い。

modelの論文を読み、GPU memoryを計算し、containerをbuildし、顧客の制約まで一つの設計へつなげたいエンジニアにとって、オープンウェイトLLMはいま最も手触りのある領域の一つです。

私たちは、この巨大で曖昧な対象を、再現できるcommandと顧客価値へ変える仲間を探しています。

麻布技術研究所のPanda Forceやキャリア開発、協業に関心がある方は、麻布技術研究所へ連絡してください

この記事を書いた人

中村泰行(Yasu Nakamura)

株式会社麻布技術研究所 代表取締役社長。 サイバーセキュリティ、人工知能、セキュアシステム、事業成長を主な専門領域としています。

著者プロフィール

ねぇ、AI成熟度を
無料で診断してみない?