「OrcaSAQ-2-27B」テキスト生成モデル:当サイトでの回答例・必要VRAM 16GB〜

2026年11月11日

「OrcaSAQ-2-27B」テキスト生成モデル:当サイトでの回答例・必要VRAM 16GB〜

基本情報

項目 内容
リポジトリ orcarouter/OrcaSAQ-2-27B
まとめページ Qwen3.8 のまとめ(記事8本)
公開元のまとめ Alibaba(Qwen) のモデルとライセンスのまとめ
公開日 2026-09-24
ライセンス apache-2.0
配布形式 EXL3 / safetensors
出典の種類 公開元の一次情報(非公式のサードパーティ量子化版で、一次情報の裏付けが不十分)

情報を集めた時点で、当サイトのコードが確定させた値です。日付はJSTで表示しています。

当サイトで確かめたこと

  • 配布元のコード(transformers ・・版 15d20d7e9a)を Modal のクラウドの GPU(NVIDIA L4・ピーク時の VRAM 14.0GB)で動かし、回答を原文のまま載せています。
  • Qwen3 のトークナイザより約21%少ないトークンで同じ日本語を表せます。同じ文脈長に入る日本語が約1.26倍になり、生成も1字あたりで速くなります。

詳しい値と条件は、下の「当サイトでの実測」の節にあります。

概要

AI ゲートウェイを運営する OrcaRouter が、Qwen3.8-27B を平均 3.21bit まで圧縮した量子化版 OrcaSAQ2 27B(orcarouter/OrcaSAQ-2-27B)を Hugging Face で公開しました。BF16 で 54GB ある元のモデルを、配布ファイルの合計 12.3GB まで縮めています。公開元が掲げる狙いは「27B のモデルを 16GB の GPU 1 枚で動かす」ことで、そのうえで元のモデルとの差が小さいことを、BF16 と直接比べた数値で示しています。

公開元はこれを「独自の感度考慮型・混合精度の量子化システム(SAQ2)」と呼び、手法の詳細(較正のやり方・層ごとのビット数の割り振り・詰め方)は公開していません。ただし配布ファイルの設定(quantization_config.json)を見ると、量子化の形式は exl3(ExLlamaV3 の形式、バージョン 1.5.1)です。公開元が同時に出した実行用のカーネルのリポジトリも、中身を「EXL3 のトレリス量子化(QTIP 系)に、探索で決めた混合精度の割り振りを組み合わせたもの」と説明しています。つまり新しい形式ではなく、既存の EXL3 形式の中で、層ごとのビット数の配分を工夫したものと読むのが正確です。

土台の Qwen3.8-27B 本体については 「Qwen3.8-27B」マルチモーダル視覚言語モデル:当サイトでの回答例・必要VRAM 8GB〜・GGUF版あり で取り上げています。

スペック

  • ベースモデル: Qwen3.8-27B(Qwen3.5 系のハイブリッド構成。64 層のうち 48 層が Gated DeltaNet、16 層が通常のアテンション)
  • 量子化: EXL3 形式、デコーダ部分の平均 3.21bit。出力層(lm_head)は 6bit、埋め込みは int8、MTP のヘッドは 4bit
  • 配布ファイル: safetensors 4 分割、合計 12.27GB
  • コンテキスト長: 262,144 トークン(設計上の上限。16GB の GPU で実際に使える長さは後述)
  • 対応機能: 思考(thinking)モード、ツール呼び出し、MTP(Multi-Token Prediction)による投機的デコード
  • 入力: テキストのみ。土台の Qwen3.8-27B は画像・動画を読めるが、この版には視覚エンコーダが入っていない
  • ライセンス: Apache-2.0(土台の Qwen3.8-27B から引き継ぎ)

性能

元のモデル(BF16)とのずれ

公開元は、配布している重みそのものを BF16 版と同じ評価経路で比べた値を載せています。WikiText-2 の 16,376 トークンで測ったものです。

→ 横にスクロールできます

ビルド サイズ デコーダのビット数 平均 KLD ↓ トップ1一致率 ↑ PPL ↓
Qwen3.8-27B BF16 54GB 16 — 100% 5.6468
OrcaSAQ2 27B 12.3GB 3.21 0.031 93.2% 5.6482

3 つの指標の意味は次のとおりです。

  • PPL(Perplexity): 文章の続きをどれだけ迷わず予測できるか。低いほど良いです。BF16 からの悪化は +0.02% で、ほぼ差がありません
  • KLD(KL ダイバージェンス): 次のトークンの確率分布が BF16 とどれだけずれたか。0 に近いほど元のモデルに忠実
  • トップ1一致率: 「次に最も選ばれやすいトークン」が BF16 と同じだった割合

この 3 つを並べて読むことが大事です。PPL の差が 0.02% しかないのに、トップ1一致率は 93.2% で、およそ 15 トークンに 1 回は BF16 と違うトークンを最有力として選んでいます。PPL は文章全体で平均した値なので、個々の選択の違いは打ち消し合って表に出にくいです。公開元自身も制約の節で「93.2% の一致は、一部のトークンの判断が BF16 と異なることを意味する」「+0.02% の PPL は下流のタスクで同じ性能を保証しない」と書いています。「ほぼ無劣化」と要約するより、「平均的な予測はほとんど変わらないが、個々の判断は一定の割合で変わる」と理解しておくのが正確です。なお、他の量子化版(GGUF や他の EXL3 版)を同じ条件で測った比較は示されていないので、KLD 0.031 が 3bit 台として優れているかどうかは、この資料だけでは判断できません。

エージェント系のベンチマーク(公開元の自己申告)

モデルカードは SWE-bench Verified で 70.0、Terminal-Bench 2.1 で 58.4 というスコアを、Claude Sonnet 4.6・Gemini 3・GPT-5.4 などの公表値と並べた表で示しています。ただし次の理由から、この記事では他のモデルとの順位としては扱いません。

  • 公開元自身が、表を「条件をそろえた比較ではなく、公開されている参考値」と断っています。エージェント系のベンチマークは、使う実行環境(ハーネス)・思考の予算・時間制限でスコアが大きく変わります
  • OrcaSAQ2 のスコアをどの実行環境・設定で測ったかが書かれていない
  • 最も知りたい「同じ条件で測った BF16 版のスコア」がありません。そのため、量子化でどれだけ落ちたのかがこの表からは分かりません

量子化版の評価として意味があるのは、前の節の「BF16 とのずれ」の方です。エージェント系のスコアは、公開元がそう申告している、という以上には読まないほうがよいです。

16GB の GPU での速度

GPU メモリを 15.7GiB に制限して vLLM で測った値。

→ 横にスクロールできます

設定 1ストリーム 8ストリーム 16ストリーム KV キャッシュの容量
MTP なし 65.3 tok/s 332 tok/s 333 tok/s 29,354 トークン
MTP あり 90.1 tok/s 220 tok/s 219 tok/s 14,563 トークン

MTP(投機的デコード)を使うと 1 人で使うときの生成は約 38% 速くなります。その代わり、下書き用のヘッドが同じメモリから KV キャッシュを取るので、文脈に使える量が約半分になり、同時に多数をさばく用途ではむしろ遅くなります。1 人で対話的に使うなら MTP あり、複数の処理を並べるなら MTP なし、という使い分けになります。

実行用カーネルのリポジトリにも同じ趣旨の表がありますが、数値が異なります(15.5GiB の制限で、MTP ありの 1 ストリームが 111.2 tok/s、KV キャッシュは MTP なしで 59,753 トークン)。設定や版の違いによるものと見られますが、どちらも公開元の測定で、第三者の再現はまだありません。

得意なこと・想定用途

公開元が想定するのは、コーディング・端末操作・ブラウザ操作などを長い手順で続けるエージェントです。量子化の小さな誤差でもツールの呼び出しが 1 回変わると、その後の状態がすべて変わっていきます ―― だから長い手順のタスクほど量子化の影響が出やすい、というのが公開元の問題意識で、「BF16 とのずれ」を細かく示しているのもそのためです。

手元で使う立場から見ると、このモデルが向いているのは 16GB の GPU(RTX 5080・4080 など)で、27B クラスのモデルをサーバーとして立てたい場合です。OpenAI 互換の API として動くので、コーディング用のエージェントや自作のツールからつなげられます。

注意点も多いです。

  • 16GB で 262K の文脈は使えません。 重みで約 12.3GB を使うため、残りは 3〜4GB 程度しかありません。公開元も「16GB の GPU では 32K 前後の文脈から始め、用途に合わせて調整する」ことを勧めています
  • 画像は読めません。 土台の Qwen3.8-27B の視覚機能は、この版では外されています
  • 量子化の手法は非公開です。 同じ手順を自分で他のモデルに適用することはできません
  • 公開元は AI ゲートウェイを運営する企業で、Hugging Face の公開モデルの多くは既存モデルの検閲解除版(Uncensored)です。この OrcaSAQ2 27B は検閲解除版ではなく、Qwen3.8-27B をそのまま量子化したものとして公開されています

類似モデルとの違い

  • 一般的な GGUF 量子化版(Q3_K_M・IQ3 系など)との違い: 大きさは近いですが、動かせるエンジンがまったく違います。GGUF は llama.cpp・Ollama・LM Studio でそのまま動くのに対し、この版はそれらでは動きません(次の節)。代わりに、BF16 とのずれを数値で示している点、vLLM で複数の要求を並べてさばける点が強みになります
  • 他の EXL3 量子化版との違い: EXL3 形式自体は ExLlamaV3 の標準の形式で、3bit 前後の版は他にも作られ得ます。OrcaSAQ2 の違いは、層ごとにビット数を変える配分の探索と、vLLM で動かすためのプラグインを用意した点にあります。ただし同じ条件で他の EXL3 版と比べた数値は示されていません
  • 土台の Qwen3.8-27B(BF16)との違い: 必要なメモリは 4 分の 1 以下になりますが、画像入力を失い、トークン単位では 93.2% の一致にとどまります。精度を最優先するなら元のモデル、16GB に収めることを優先するならこの版、という選び方になります

動作環境

動作環境の目安(Local Model Watch 算出) — パラメータ数 27.8B(元モデル Qwen/Qwen3.8-27B の値)

手持ちのVRAM 選べる量子化 ファイルサイズ 必要メモリの目安
RTX 5060 Ti 16GB / 4060 Ti 16GB など 16GB EXL3 11.4GB 13.7GB

必要メモリは配布ファイルの実サイズに実行時のオーバーヘッド(KVキャッシュ等)を20%見込んだ概算で、文脈長・バッチサイズ・推論エンジンによって増減します。公開元の公称値ではなく、当サイトがファイルサイズから機械的に算出した値です。 他のモデルとの比較はVRAM別の早見表を参照してください。 量子化の名前の読み方は用語集にあります。

手元で動かせるか

現時点では Ollama・LM Studio・llama.cpp で動かせません(GGUF版を確認できていない)。

公開元の配布は EXL3 / safetensors のみです。現時点で動かすなら transformers(PyTorch) で読み込む形になり、必要メモリは上の表のとおりです。

ライセンス apache-2.0(商用利用可): 商用利用を含めて自由に利用・改変・再配布できます。再配布時にライセンス文と変更点の告知が必要で、特許の許諾条項があります。

配布形式・当サイトが見つけた変換版・各推論エンジンの登録表を突き合わせた判定です。「確認できていない」は当サイトが見つけていないという意味で、存在しないことの断定ではありません。ライセンスの要約は法的助言ではないため、実際の利用にあたっては公開元の原文を確認してください。

当サイトでの実測

モデルカードの記載ではなく、当サイトが測った結果です。ファイルの中身は当サイトのサーバー(GPUなし)で読み込んで確かめ、このモデルはそのサーバーでは動かせないため、クラウドの GPU を借りて動かしました(条件は下記)。測り方と全モデルの一覧は観測データにまとめています。

実測から分かったこと

OrcaSAQ-2-27Bは、日本語のトークン効率が良く、限られた文脈長の中に多くの情報を詰め込めるモデルです。一方で、知識を問う問題や長い文章の生成では、回答が打ち切られたり、同じ行が繰り返されたりする不安定さが見られました。日本語のトークン効率は1000字あたり546トークンであり、Qwen3の688トークンと比較して少ないトークン数で日本語を処理できます。

クラウドのGPU(NVIDIA L4)でEXL3 3.21bit形式を用いて検証したところ、モデルの読み込みには13.7GBのVRAMを消費し、生成中の最大値は14.0GBでした。生成速度は17.19トークン/秒という結果でした。この環境下では、要約や俳句の作成、買い物の文章題といったタスクでは指示通りの回答が得られ、文章題では正解の280円を導き出しています。

しかし、海に面していない県を挙げる知識問題では、1,024トークンの上限に達して回答が途中で打ち切られました。この際、同じ行が11回繰り返される現象が発生し、8県のうち4県しか挙げられず、海に面している県を誤って含める結果となりました。また、取引先へのメール作成でも同じ行の繰り返しが2回見られるなど、長文生成や特定の知識を問う場面での挙動には注意が必要です。

日本語のトークン効率

トークナイザ 日本語1,000字あたりのトークン数 同じ内容の英文との比
このモデル 546 0.99倍
Qwen3 688 1.26倍
Llama 3.2 744 1.36倍
Gemma 3 564 1.03倍
gpt-oss 795 1.45倍
LLM-jp-3 497 0.85倍

Qwen3 のトークナイザより約21%少ないトークンで同じ日本語を表せます。同じ文脈長に入る日本語が約1.26倍になり、生成も1字あたりで速くなります。

orcarouter/OrcaSAQ-2-27B の tokenizer.json で、当サイトが書き下ろした固定の文章(876字。ニュース・会話・技術文書・敬語のメール・紀行文・料理の6種)と、同じ内容の英文を数えました。トークン数が少ないほど、同じ文脈長に長い日本語が入ります。

EXL3 の重みを ExLlamaV3 で動かした結果(クラウドのGPU)

llama.cpp は EXL3 形式を読めないため、この配布のファイルを、EXL3 用のオープンソースの推論エンジン ExLlamaV3 でクラウドの GPU で動かしました。配布元のリポジトリのコードは実行しておらず、ネットワークを遮断したコンテナの中で実行しています。

項目 結果
重みのファイル 11.4GB
重みを読み込んだ直後のVRAM(16384トークン分のKVキャッシュを含む) 13.7GB
5問に答えている間の最大のVRAM 14.0GB
生成(5問の回答の中央値・ExLlamaV3) 17.2 トークン/秒
生成を日本語の字数に換算 約31.5字/秒

条件: Modal の NVIDIA L4(VRAM 22GB)・ExLlamaV3 1.5.3・PyTorch 2.8.0+cu128・orcarouter/OrcaSAQ-2-27B の版 15d20d7e9a(EXL3 3.21bit・貪欲デコード・思考オフ)・2026-10-01に測定しました。

速さは、この1つの GPU とこのエンジンでの参考値です。llama.cpp や別の GPU で同じ速さが出るとは限りません。なお、この配布の埋め込み層は int8 の値と行ごとの倍率に分けて保存されており、ExLlamaV3 はそのままでは読めないため、読み込みの前に当サイトで掛け合わせて bf16 の重みに戻しました(コードは下の手順に載せています)。この変換は配布元が文書にしていないため、形式についての当サイトの解釈です。

日本語の質問への回答(原文のまま)

上の条件で、全モデルに同じ5問を日本語で尋ねた回答を、手を加えずに載せています(温度0・チャットテンプレートが対応していれば思考なし・最大1024トークン)。正誤は判定していません。答えが1つに決まる問いには、正解を併記します。

要約

次の記事を3文で要約してください。

みどり市は今年の春、市内に三つある公立図書館のうち最も古い中央図書館の改修を終え、十月一日に再開館した。改修は約一年半にわたり、総事業費は約十二億円。このうち約四億円は国の補助金でまかなわれた。

最大の変化は、閲覧席の配置である。以前は館内の座席の大半が学習用の机で、試験期間になると中高生で埋まり、高齢の利用者や小さな子ども連れが座れないという苦情が毎年寄せられていた。改修後は座席数を百二十席から二百席に増やしたうえで、学習用の机を三階にまとめ、一階は会話ができる「にぎわいフロア」、二階は静かに本を読む「閲覧フロア」に分けた。一階には予約制のグループ学習室が四室と、飲み物を持ち込めるカフェスペースも設けられた。

蔵書の面でも見直しが進んだ。貸出の少ない古い資料約三万冊を市内の他の館や保存書庫に移し、代わりに子ども向けの絵本と、介護・子育て・仕事探しといった暮らしに関わる実用書を約一万五千冊増やした。電子書籍の貸出サービスも始まり、利用登録をすれば自宅から一度に三冊まで、二週間借りられる。

建物そのものにも手が入った。築四十年を超えていた空調設備を入れ替え、屋上には太陽光パネルを設置して、館内で使う電力の約二割をまかなえるようにした。車いすの利用者から要望の多かったエレベーターは一基から二基に増え、書架の間の通路も以前より三十センチ広げられた。入口には段差のないスロープが新たに設けられ、授乳室と多目的トイレも各階に一つずつ置かれた。

一方で課題も残る。駐車場は改修前と同じ四十台のままで、週末には近くの道路に順番待ちの車が並んだ。市は隣接する市有地を臨時駐車場として開放したが、恒久的な対策は決まっていない。また、開館時間を平日の夜九時まで延ばしたことで職員の負担が増えており、職員団体は人員の追加を求めている。

利用者の受け止めはおおむね好意的だ。週に二度、孫を連れて来るという七十代の女性は「前は子どもが声を出すと周りの目が気になったが、一階なら気兼ねなく絵本を読んであげられる」と話す。一方、受験を控えた高校生の中には「学習席が三階だけになり、夕方はすぐに満席になる」と不満を漏らす人もいる。図書館は、学習席の空き状況をホームページで確認できる仕組みを年内に導入する予定だ。

再開館に合わせて、催しも増えた。毎週土曜の午前には読み聞かせ会、月に一度は地元の農家や商店主を講師に招く「まちの先生」講座が開かれる。十一月には、市内の中学生が選んだ本を紹介する展示も予定されている。

館長の山本和子さんは「本を借りる場所から、人が集まって過ごす場所へ変えたかった。再開館からの一か月で来館者は以前の一・八倍になった」と話す。市は来年度、残る二つの図書館についても利用者への聞き取りを行い、改修の必要性を検討する方針だ。

みどり市中央図書館は約12億円の改修を経て再開し、フロアごとの機能分化や蔵書の見直し、バリアフリー対応などを通じて、単なる閲覧施設から地域交流の場へと転換した。その結果、来館者は以前比1.8倍に増加し、多様な利用者のニーズに応える環境が整った一方、駐車場不足や職員負担増といった課題も残っている。市は今後の利用者調査を通じて残る2館の改修必要性を検討し、図書館機能のさらなる充実を図る方針を示している。

敬語のメール

取引先の担当者に、来週火曜日の打ち合わせを水曜日に変更してほしいとお願いするメールを、丁寧な敬語で書いてください。

件名:【ご相談】来週火曜日の打ち合わせ日程変更のお願い

○○株式会社
○○部 ○○様

いつも大変お世話になっております。
株式会社△△の△△です。

突然のご連絡となり、大変失礼いたします。

来週火曜日(○月○日)に予定しております打ち合わせの件で、誠に恐れ入りますが、日程の変更をお願いしたくご連絡いたしました。

社内事情により、当日の参加予定者が都合つかない状況となりましたため、もし可能であれば、**翌日の水曜日(○月○日)**に変更させていただくことは可能でしょうか。

つきましては、以下の日程で改めてご調整いただけますと幸いです。

■希望日程
○月○日(水) 10:00〜12:00
※上記の時間帯で調整が難しい場合は、水曜日の他の時間帯や、以降の日程でもご相談に応じます。

ご多忙のところ、急なお願いとなり大変申し訳ございません。
ご確認のほど、何卒よろしくお願い申し上げます。

―――――――――――――――――――
株式会社△△
△△部 △△(氏名)
TEL: 03-XXXX-XXXX
Mail: xxxxx@xxxx.com
―――――――――――――――――――

文章題

りんごが1個120円、みかんが1個45円です。りんごを3個とみかんを8個買って、1,000円札で払いました。おつりはいくらですか。考え方も示してください。

おつりの金額を求めるために、まずりんごとみかんの合計代金を計算し、そこから1,000円を引く手順で考えます。

### 1. 考え方の手順

1.  **りんごの代金**を計算する。
    *   単価 × 個数
2.  **みかんの代金**を計算する。
    *   単価 × 個数
3.  **合計代金**を計算する。
    *   りんごの代金 + みかんの代金
4.  **おつり**を計算する。
    *   支払った金額(1,000円) - 合計代金

---

### 2. 計算過程

**① りんごの代金**
$$ 120 \text{円} \times 3 = 360 \text{円} $$

**② みかんの代金**
$$ 45 \text{円} \times 8 = 360 \text{円} $$

**③ 合計代金**
$$ 360 \text{円} + 360 \text{円} = 720 \text{円} $$

**④ おつり**
$$ 1,000 \text{円} - 720 \text{円} = 280 \text{円} $$

---

### 3. 答え

おつりは **280円** です。

参考: 正解は280円です(120×3=360円、45×8=360円、1,000−720=280円)。

知識

日本の都道府県のうち、海に面していない県をすべて挙げてください。

日本の都道府県の中で、海に面していない(内陸県)のは以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **三重県**(※注:三重県は伊勢湾に面しているため、厳密には海に面しています。しかし、多くの文脈で「内陸県」として扱われることがありますが、地理的には海に面しています。ここでは**海に面していない**という厳密な定義に基づき、三重県は除外します。)

※訂正:三重県は伊勢湾に面しているため、海に面しています。したがって、内陸県ではありません。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**(琵琶湖は湖であり、海ではないため内陸県とされます)
5. **愛知県**(※注:愛知県は太平洋と伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:愛知県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **三重県**(※伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:三重県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **愛知県**(※太平洋と伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:愛知県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **三重県**(※伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:三重県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **愛知県**(※太平洋と伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:愛知県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **三重県**(※伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:三重県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **愛知県**(※太平洋と伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:愛知県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **三重県**(※伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:三重県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県**
3. **岐阜県**
4. **滋賀県**
5. **愛知県**(※太平洋と伊勢湾に面しているため、海に面しています。内陸県ではありません。)

※再度確認:愛知県は海に面しています。

正しい内陸県(海に面していない県)は以下の**9県**です。

1. **山梨県**
2. **長野県

(1024トークンの上限で打ち切り)

参考: 正解は8県です(栃木県・群馬県・埼玉県・山梨県・長野県・岐阜県・滋賀県・奈良県)。

指示どおりの創作

「春」をテーマにした俳句を3つ、五・七・五の音数を守って作ってください。それぞれに一言の説明を付けてください。

ご指定の条件に基づき、「春」をテーマにした俳句を3つ作成しました。それぞれに一言の解説を添えています。

1. **花吹雪 舞い散る空に 春の風**
   > 解説:桜の花びらが舞い散る情景と、その中を抜ける柔らかな風で、春の移ろいを表現しました。

2. **新緑の 木漏れ日揺れて 春の光**
   > 解説:若葉が茂り始めた木々から差し込む、揺れる光の美しさを捉えました。

3. **蛙鳴く 田んぼの春の 朝の空気**
   > 解説:田んぼで鳴き始める蛙の声と、清々しい朝の空気感で、春の生命力を表現しました。

環境構築・ダウンロード・実行の手順(当サイトで実行したもの)

当サイトでは、ダウンロードと実行を Modal の2つのコンテナに分けました。ダウンロードのコンテナは Debian(slim)・Python 3.12 のイメージで、ファイルを取るだけです。実行のコンテナは nvidia/cuda:12.8.1-devel-ubuntu22.04・Python 3.12 のイメージで、ネットワークを遮断しています。ExLlamaV3 の CUDA の拡張はイメージを作るときにコンパイルしており、GPU の上ではコンパイルしません。次が2つの環境を作ったコマンドです。

# 1. ダウンロード用の実行環境を作る(GPU なし)
python -m pip install huggingface_hub

# 2. 実行用の実行環境を作る(GPU あり・ネットワークなし)
export TORCH_CUDA_ARCH_LIST="8.0;8.9" MAX_JOBS="4"
pip install torch==2.8.0 --index-url https://download.pytorch.org/whl/cu128
pip install transformers jinja2 ninja setuptools wheel
pip install --no-build-isolation exllamav3==1.5.3

そのうえで、remote_code_remote.py の download(job) を1つ目のコンテナで、exl3_remote.py の run(job) を2つ目のコンテナで呼びました(どちらも当サイトが書いたもの。2つ目は下に全文)。ファイルの置き場所は /models/<dir> です。

"""
Modal のコンテナの中で動く、ExLlamaV3 による EXL3 形式のモデルの実測(2026-09-30)。
lmw/lab/gpu_modal.py の run_exl3 から呼ばれる。ダウンロードは remote_code_remote.download を使う
(重みは safetensors だけ・配布元のコードは落とさず実行もしない)。

実行するコンテナはネットワーク遮断・Modal の機能も使えない・Volume は読み取り専用。ExLlamaV3 は pip の公開
パッケージで、配布元のリポジトリのコードは入れない(配布元が別に配っているカーネルも使わない)。
記事執筆用の LLM は呼ばない。回答の良し悪しも判定しない(原文を返すだけ)。
"""
import json
import os
import platform
import time
from datetime import datetime, timezone

from lmw.lab.remote_code_remote import MOUNT, _log, installed_packages, plain, split_thinking

from lmw.config import (
    LAB_EXL3_CUDA_ARCHS, LAB_EXL3_CUDA_IMAGE, LAB_EXL3_PYTHON, LAB_EXL3_TORCH, LAB_EXL3_TORCH_INDEX, LAB_EXL3_VERSION,
)

# 実行用のイメージの作り方(lmw/lab/gpu_modal.py が実行し、記事の手順にも同じ値を載せる)
BASE_IMAGE = LAB_EXL3_CUDA_IMAGE
PYTHON_VERSION = LAB_EXL3_PYTHON
BUILD_ENV = {"TORCH_CUDA_ARCH_LIST": LAB_EXL3_CUDA_ARCHS, "MAX_JOBS": "4"}
INSTALL_COMMANDS = (
    f"pip install torch=={LAB_EXL3_TORCH} --index-url {LAB_EXL3_TORCH_INDEX}",
    "pip install transformers jinja2 ninja setuptools wheel",
    f"pip install --no-build-isolation exllamav3=={LAB_EXL3_VERSION}",
)

def _stop_ids(path: str, tokenizer) -> list[int]:
    """generation_config.json の eos(整数か一覧)。無ければトークナイザの eos。"""
    ids: list[int] = []
    try:
        with open(os.path.join(path, "generation_config.json"), encoding="utf-8") as f:
            eos = json.load(f).get("eos_token_id")
        ids = [int(x) for x in (eos if isinstance(eos, list) else [eos])] if eos is not None else []
    except (OSError, ValueError):
        pass
    if not ids and tokenizer.eos_token_id is not None:
        ids = [int(tokenizer.eos_token_id)]
    return ids

def _prompt_text(path: str, text: str) -> str:
    from transformers import AutoTokenizer
    tok = AutoTokenizer.from_pretrained(path, local_files_only=True)
    if not getattr(tok, "chat_template", None):
        return ""
    messages = [{"role": "user", "content": text}]
    try:
        return tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True, enable_thinking=False)
    except TypeError:
        return tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

def _dequantize_embedding(src: str) -> tuple[str, str]:
    """
    埋め込みが qweight(int8)+scales(行ごとの bf16)で保存されている配布(quantization_config.json は
    bf16 の weight と書いている)を、ExLlamaV3 が読める weight に直した作業用フォルダを /tmp に作る
    (Volume は読み取り専用)。戻り値: (フォルダ, 直したことの説明)。埋め込みが標準の形なら何もしない。
    """
    import glob
    import shutil
    import torch
    from safetensors import safe_open
    from safetensors.torch import save_file
    prefix = "model.language_model.embed_tokens"
    holder = None
    for f in sorted(glob.glob(os.path.join(src, "*.safetensors"))):
        with safe_open(f, "pt") as st:
            keys = set(st.keys())
        if f"{prefix}.weight" in keys:
            return src, ""
        if f"{prefix}.qweight" in keys:
            holder = f
    if holder is None:
        return src, ""
    with safe_open(holder, "pt") as st:
        q = st.get_tensor(f"{prefix}.qweight")
        scales = st.get_tensor(f"{prefix}.scales")
    weight = (q.to(torch.float32) * scales.to(torch.float32)[:, None]).to(torch.bfloat16).contiguous()
    work = "/tmp/exl3-model"
    shutil.rmtree(work, ignore_errors=True)
    os.makedirs(work)
    for name in os.listdir(src):
        os.symlink(os.path.join(src, name), os.path.join(work, name))
    save_file({f"{prefix}.weight": weight}, os.path.join(work, "embed-dequantized.safetensors"))
    return work, "埋め込み: int8 の qweight × 行ごとの scales を bf16 の weight に直して読み込み"

def run(job: dict) -> dict:
    """
    job: {"dir", "prompts": [{"id", "ja"}], "max_tokens", "cache_tokens", "answer_budget_sec"}。
    チャットテンプレートが無ければ {"no_chat_template": True}。
    """
    import exllamav3
    import torch
    from exllamav3 import Cache, Config, Generator, Job, Model, Tokenizer
    from exllamav3.generator.sampler import CustomSampler, SS_Argmax
    os.environ["HF_HUB_OFFLINE"] = "1"
    os.environ["TRANSFORMERS_OFFLINE"] = "1"
    t0 = time.time()
    path = os.path.join(MOUNT, job["dir"])
    gpu = torch.cuda.get_device_name(0)
    vram_total = torch.cuda.get_device_properties(0).total_memory
    from importlib import metadata
    version = getattr(exllamav3, "__version__", "") or metadata.version("exllamav3")
    _log(t0, f"GPU: {gpu}・exllamav3 {version}・torch {torch.__version__}")
    with open(os.path.join(path, "quantization_config.json"), encoding="utf-8") as f:
        quant = json.load(f)
    record = {"runtime": "exllamav3", "gpu": gpu, "vram_total": int(vram_total), "exllamav3": str(version),
              "torch": str(torch.__version__), "packages": installed_packages(),
              "python": platform.python_version(), "cache_tokens": int(job["cache_tokens"]),
              "quant_method": quant.get("quant_method"), "quant_version": quant.get("version"),
              "bits": quant.get("bits"), "head_bits": quant.get("head_bits"),
              "measured_at": datetime.now(timezone.utc).isoformat()}
    first = _prompt_text(path, job["prompts"][0]["ja"])
    if not first:
        _log(t0, "チャットテンプレートがありません")
        return plain({**record, "no_chat_template": True})
    path, note = _dequantize_embedding(path)
    if note:
        record["embed_dequant"] = note
        _log(t0, note)
    config = Config.from_directory(path)
    model = Model.from_config(config)
    cache = Cache(model, max_num_tokens=job["cache_tokens"])
    model.load(progressbar=False)
    tokenizer = Tokenizer.from_config(config)
    generator = Generator(model=model, cache=cache, tokenizer=tokenizer)
    torch.cuda.synchronize()
    record["vram_loaded"] = int(torch.cuda.memory_allocated())
    record["load_sec"] = round(time.time() - t0)
    _log(t0, f"読み込み: VRAM {record['vram_loaded'] / 1024 ** 3:.1f}GB・{record['load_sec']}秒")
    torch.cuda.reset_peak_memory_stats()
    stops = _stop_ids(path, tokenizer)
    sampler = CustomSampler([SS_Argmax()])
    outputs = []
    stop_at = t0 + job.get("answer_budget_sec", 10 ** 9)
    for prompt in job["prompts"]:
        slowest = min((o["gen_tps"] for o in outputs if o.get("gen_tps")), default=None)
        worst = job["max_tokens"] / slowest if slowest else 0
        if time.time() + worst > stop_at:
            _log(t0, f"時間の上限が近いため、残りの問い({prompt['id']} から)は尋ねません")
            record["unanswered"] = [p["id"] for p in job["prompts"][len(outputs):]]
            break
        text = _prompt_text(path, prompt["ja"])
        ids = tokenizer.encode(text, add_bos=False, encode_special_tokens=True)
        started = time.time()
        gen_job = Job(input_ids=ids, max_new_tokens=job["max_tokens"], stop_conditions=stops, sampler=sampler,
                      decode_special_tokens=True)
        generator.enqueue(gen_job)
        pieces: list[str] = []
        count = 0
        eos_reason = ""
        while generator.num_remaining_jobs():
            for result in generator.iterate():
                if result.get("stage") != "streaming":
                    continue
                pieces.append(result.get("text", ""))
                if result.get("eos"):
                    count = int(result.get("new_tokens", 0))
                    eos_reason = str(result.get("eos_reason", ""))
        torch.cuda.synchronize()
        seconds = time.time() - started
        answer, thinking = split_thinking("".join(pieces), text[-64:])
        for special in ("<|im_end|>", "<|endoftext|>", "<|im_start|>"):
            answer = answer.replace(special, "")
        outputs.append({
            "id": prompt["id"],
            "content": answer.strip(),
            "reasoning_chars": len(thinking.strip()),
            "finish_reason": "length" if eos_reason == "max_new_tokens" or count >= job["max_tokens"] else "stop",
            "completion_tokens": count,
            "gen_tps": round(count / seconds, 2) if seconds > 0 and count else None,
            "prompt_tokens": int(ids.shape[-1]),
        })
        _log(t0, f"回答 {prompt['id']}: {count}トークン・{outputs[-1]['gen_tps']} トークン/秒")
    record["vram_peak"] = int(torch.cuda.max_memory_allocated())
    record["outputs"] = outputs
    gen = sorted(o["gen_tps"] for o in outputs if o.get("gen_tps"))
    if gen:
        record["tg_tps"] = gen[len(gen) // 2]
    return plain(record)

download に渡した job(実際に使った値):

{
  "repo": "orcarouter/OrcaSAQ-2-27B",
  "revision": "15d20d7e9ae4fd89d1a47878f69381760169445b",
  "files": [
    "chat_template.jinja",
    "config.json",
    "generation_config.json",
    "merges.txt",
    "model-00001-of-00004.safetensors",
    "model-00002-of-00004.safetensors",
    "model-00003-of-00004.safetensors",
    "model-00004-of-00004.safetensors",
    "model.safetensors.index.json",
    "preprocessor_config.json",
    "quantization_config.json",
    "tokenizer.json",
    "tokenizer_config.json",
    "video_preprocessor_config.json",
    "vocab.json"
  ],
  "dir": "run-1790831352"
}

run に渡した job(実際に使った値):

{
  "dir": "run-1790831352",
  "max_tokens": 1024,
  "cache_tokens": 16384,
  "answer_budget_sec": 2220,
  "prompts": [
    {
      "id": "summary",
      "ja": "次の記事を3文で要約してください。\n\nみどり市は今年の春、市内に三つある公立図書館のうち最も古い中央図書館の改修を終え、十月一日に再開館した。改修は約一年半にわたり、総事業費は約十二億円。このうち約四億円は国の補助金でまかなわれた。\n\n最大の変化は、閲覧席の配置である。以前は館内の座席の大半が学習用の机で、試験期間になると中高生で埋まり、高齢の利用者や小さな子ども連れが座れないという苦情が毎年寄せられていた。改修後は座席数を百二十席から二百席に増やしたうえで、学習用の机を三階にまとめ、一階は会話ができる「にぎわいフロア」、二階は静かに本を読む「閲覧フロア」に分けた。一階には予約制のグループ学習室が四室と、飲み物を持ち込めるカフェスペースも設けられた。\n\n蔵書の面でも見直しが進んだ。貸出の少ない古い資料約三万冊を市内の他の館や保存書庫に移し、代わりに子ども向けの絵本と、介護・子育て・仕事探しといった暮らしに関わる実用書を約一万五千冊増やした。電子書籍の貸出サービスも始まり、利用登録をすれば自宅から一度に三冊まで、二週間借りられる。\n\n建物そのものにも手が入った。築四十年を超えていた空調設備を入れ替え、屋上には太陽光パネルを設置して、館内で使う電力の約二割をまかなえるようにした。車いすの利用者から要望の多かったエレベーターは一基から二基に増え、書架の間の通路も以前より三十センチ広げられた。入口には段差のないスロープが新たに設けられ、授乳室と多目的トイレも各階に一つずつ置かれた。\n\n一方で課題も残る。駐車場は改修前と同じ四十台のままで、週末には近くの道路に順番待ちの車が並んだ。市は隣接する市有地を臨時駐車場として開放したが、恒久的な対策は決まっていない。また、開館時間を平日の夜九時まで延ばしたことで職員の負担が増えており、職員団体は人員の追加を求めている。\n\n利用者の受け止めはおおむね好意的だ。週に二度、孫を連れて来るという七十代の女性は「前は子どもが声を出すと周りの目が気になったが、一階なら気兼ねなく絵本を読んであげられる」と話す。一方、受験を控えた高校生の中には「学習席が三階だけになり、夕方はすぐに満席になる」と不満を漏らす人もいる。図書館は、学習席の空き状況をホームページで確認できる仕組みを年内に導入する予定だ。\n\n再開館に合わせて、催しも増えた。毎週土曜の午前には読み聞かせ会、月に一度は地元の農家や商店主を講師に招く「まちの先生」講座が開かれる。十一月には、市内の中学生が選んだ本を紹介する展示も予定されている。\n\n館長の山本和子さんは「本を借りる場所から、人が集まって過ごす場所へ変えたかった。再開館からの一か月で来館者は以前の一・八倍になった」と話す。市は来年度、残る二つの図書館についても利用者への聞き取りを行い、改修の必要性を検討する方針だ。"
    },
    {
      "id": "keigo",
      "ja": "取引先の担当者に、来週火曜日の打ち合わせを水曜日に変更してほしいとお願いするメールを、丁寧な敬語で書いてください。"
    },
    {
      "id": "arithmetic",
      "ja": "りんごが1個120円、みかんが1個45円です。りんごを3個とみかんを8個買って、1,000円札で払いました。おつりはいくらですか。考え方も示してください。"
    },
    {
      "id": "prefectures",
      "ja": "日本の都道府県のうち、海に面していない県をすべて挙げてください。"
    },
    {
      "id": "haiku",
      "ja": "「春」をテーマにした俳句を3つ、五・七・五の音数を守って作ってください。それぞれに一言の説明を付けてください。"
    }
  ]
}
実行のコンテナに入っていたパッケージの版(全文)
aiohappyeyeballs==2.6.1 aiohttp==3.12.7 aiosignal==1.3.2 annotated-doc==0.0.5 annotated-types==0.8.0 anyio==4.15.1 attrs==25.3.0 cbor2==5.7.0 certifi==2026.7.22 click==8.5.0 exllamav3==1.5.3 filelock==3.32.3 frozenlist==1.6.0 fsspec==2026.7.0 grpclib==0.4.8 h11==0.16.0 h2==4.2.0 hf-xet==1.6.0 hpack==4.1.0 httpcore==1.0.9 httpx==0.28.1 huggingface_hub==1.33.0 hyperframe==6.1.0 idna==3.20 Jinja2==3.1.6 llguidance==1.9.0 marisa-trie==1.4.1 markdown-it-py==4.2.0 MarkupSafe==3.0.3 mdurl==0.1.2 mpmath==1.3.0 multidict==6.4.4 networkx==3.6.1 ninja==1.13.2 numpy==2.5.3 nvidia-cublas-cu12==12.8.4.1 nvidia-cuda-cupti-cu12==12.8.90 nvidia-cuda-nvrtc-cu12==12.8.93 nvidia-cuda-runtime-cu12==12.8.90 nvidia-cudnn-cu12==9.10.2.21 nvidia-cufft-cu12==11.3.3.83 nvidia-cufile-cu12==1.13.1.3 nvidia-curand-cu12==10.3.9.90 nvidia-cusolver-cu12==11.7.3.90 nvidia-cusparse-cu12==12.5.8.93 nvidia-cusparselt-cu12==0.7.1 nvidia-nccl-cu12==2.27.3 nvidia-nvjitlink-cu12==12.8.93 nvidia-nvtx-cu12==12.8.90 packaging==26.3 pillow==12.3.0 pip==23.3.2 propcache==0.3.1 protobuf==6.31.1 pydantic==2.13.5 pydantic_core==2.46.5 Pygments==2.21.0 PyYAML==6.0.3 regex==2026.9.29 rich==15.0.0 safetensors==0.8.0 setuptools==69.0.3 shellingham==1.5.4 sympy==1.14.0 tokenizers==0.23.2 torch==2.8.0+cu128 tqdm==4.70.1 transformers==5.17.0 triton==3.4.0 typer==0.27.2 typing-inspection==0.4.4 typing_extensions==4.16.0 wheel==0.48.0 yarl==1.20.0
ダウンロードのコンテナに入っていたパッケージの版(全文)
aiohappyeyeballs==2.6.1 aiohttp==3.12.7 aiosignal==1.3.2 anyio==4.15.1 attrs==25.3.0 cbor2==5.7.0 certifi==2025.4.26 click==8.5.0 filelock==4.0.7 frozenlist==1.6.0 fsspec==2026.9.0 grpclib==0.4.8 h11==0.16.0 h2==4.2.0 hf-xet==1.6.0 hpack==4.1.0 httpcore2==2.13.1 httpx2==2.13.1 huggingface_hub==2.0.0 hyperframe==6.1.0 idna==3.20 multidict==6.4.4 packaging==26.3 pip==25.1.1 propcache==0.3.1 protobuf==6.31.1 PyYAML==6.0.3 tqdm==4.70.1 truststore==0.10.4 typing_extensions==4.16.0 uv==0.7.19 wheel==0.45.1 yarl==1.20.0

同クラスの既報モデル

当サイトが最近取り上げた、パラメータ数 15〜40B のモデルを、比較のために記事ログからコードが並べたものです。VRAM階層は当サイトの概算、ライセンスはモデルカードの記載です。

→ 横にスクロールできます

モデル パラメータ数 最小のVRAM階層 ライセンス 記事
elyza/ELYZA-Thinking-1.0-llm-jp-4-32b-a3b 32.1B 80GB apache-2.0 推論モデル「ELYZA-Thinking-1.0」の32B/33Bモデル公開(2026-10-02)
XingChen-AGI/Xing4.0-29B-A4B 31.2B 24GB apache-2.0 「Xing4.0-29B-A4B」テキスト生成モデル:当サイトでの回答例・必要VRAM 24GB〜(2026-09-28)
Edge0/Edge0-35B-A3B-preview 36.0B 24GB apache-2.0 「Edge0-35B-A3B-preview」スマホクラスで動く35BのMoEモデル:必要VRAM 24GB〜(2026-09-11)
bartowski/Gryphe_Pantheon-Reasoning-26B-A4B-1.1-V2-GGUF 26.5B 12GB apache-2.0 「Gryphe_Pantheon-Reasoning-26B-A4B-1.1-V2-GGUF」:当サイトでの回答例(2026-09-11)
nex-agi/Nex-N2.5-mini 35.1B 16GB apache-2.0 「Nex-N2.5-mini」長期タスク向けのエージェントモデル:当サイトでの回答例・必要VRAM 16GB〜(2026-09-09)

入手方法

  • 配布: Hugging Face の orcarouter/OrcaSAQ-2-27B(safetensors、EXL3 形式)
  • llama.cpp・Ollama・LM Studio では動きません。 実行用カーネルのリポジトリは「llama.cpp は独自の量子化の符号表しか読めないため、この重みは使えない。GGUF にするには別の量子化器で量子化し直すことになる」と明言している
  • vLLM で動かす場合: vLLM に加えて、公開元のプラグイン(Continuum-AI-Corp/OrcaSAQ2-kernel)を入れる必要があります。モデルカードは pip install git+https://github.com/Continuum-AI-Corp/OrcaSAQ2-kernel を案内しており、カーネルのリポジトリには 16GB 向けの起動設定と Docker イメージも用意されています。思考の出力とツール呼び出しを正しく受け取るには --reasoning-parser qwen3 と --tool-call-parser qwen3_xml を付けます
  • ExLlamaV3 で動かす場合: カーネルのリポジトリは「1 人で消費者向けの GPU で使うなら vLLM より軽く、こちらの方が向く」としています。ただし int8 で詰めた埋め込みを読むためのパッチを先に当てる必要があります。なお、ExLlamaV3 で MTP を使うと下書き用のヘッドが別にキャッシュを持つため、メモリが約 10GB 増え、16GB の GPU には収まらないとされています
  • 推奨のサンプリング設定: temperature 1.0・top_p 0.95・top_k 20。思考モードは既定で有効
  • 実行用カーネルのリポジトリは 9 月 24 日に作られたばかりで、公開から日が浅いです。環境によってはうまく動かない可能性を見込んでおきたいです
  • ライセンス: モデルは Apache-2.0(土台の Qwen3.8-27B から引き継ぎ)。利用前にライセンスの原文を確認してほしい

関連記事

次に読むなら

出典

更新履歴

  • 2026-09-28: 当サイトでの実測(日本語のトークン効率)を追加しました。
  • 2026-09-29: 公式の一次情報で内容を確認しました。出典に該当モデルが存在し、VRAM情報も整合します。
  • 2026-10-01: 当サイトでの実測(配布元のコードで動かしたVRAMと日本語の質問への回答)を追加しました。
  • 2026-10-01: タイトルを、記事で分かる内容(必要VRAM・配布ファイル等)を示す形に変更しました。