ようこそ Gemma 4: デバイス上でのフロンティアなマルチモーダル・インテリジェンス
これらのモデルは本物です。Apache 2ライセンスで真にオープンであり、高品質でパレートフロンティア・アリーナのスコアが高く、音声を含むマルチモーダル対応。そしてサイズはどこでも使える(オンデバイスを含む)形です。Gemma 4は、これまでのファミリーの進歩を土台にしており、部品がきちんと噛み合うように作られています。リリース前のチェックポイントで行ったテストでは、その能力に驚かされました。あまりにすぐれているため、手を加えてうまく使うための良い微調整の例を見つけるのに苦労するほどでした。
Googleとコミュニティと協力して、あらゆる場所で使えるようにしました。transformers、llama.cpp、MLX、WebGPU、Rust――挙げればきりがありません。このブログ記事では、お気に入りのツールでどう作り込んでいくかを紹介しますので、ぜひご意見を聞かせてください!
目次
Gemma 4で新しくなったことは?
Gemma-3nと同様に、Gemma 4は画像・テキスト・音声の入力をサポートし、テキスト応答を生成します。テキストデコーダは長いコンテキストウィンドウに対応したGemmaモデルに基づいています。画像エンコーダはGemma 3のものに似ていますが、重要な改善が2点あります。1つ目は可変アスペクト比、2つ目は、速度・メモリ・品質のバランスにおける最適点を見つけるために画像トークン入力数を設定可能にしたことです。すべてのモデルが画像(または動画)とテキスト入力をサポートし、小型のバリアント(E2BおよびE4B)は音声もサポートします。
Gemma 4は4つのサイズがあり、すべてベースモデルおよび指示(instruction)で微調整されています。
| モデル | パラメータサイズ | コンテキストウィンドウ | チェックポイント |
|---|---|---|---|
| Gemma 4 E2B | 2.3B(有効)/ 5.1B(埋め込み込み) | 128k | base, IT |
| Gemma 4 E4B | 4.5B(有効)/ 8B(埋め込み込み) | 128k | base, IT |
| Gemma 4 31B | 31Bの密(dense)モデル | 256K | base, IT |
| Gemma 4 26B A4B | 4Bが有効化される(4B activated)/ 合計26Bパラメータのモジュール・エキスパート(mixture-of-experts) | 256K | base, IT |
能力とアーキテクチャの概要
Gemma 4は、これまでのGemmaバージョンや他のオープンモデルで使われているいくつかのアーキテクチャ構成要素を活用し、Altupのような複雑であったり結論が出ない特徴は除外しています。これらの組み合わせは、ライブラリやデバイス間で高い互換性を持つことを目指して設計されたもので、長いコンテキストやエージェント型のユースケースを効率的にサポートしつつ、量子化にとっても理想的です。
上記のベンチマークに示される通り、この特徴の組み合わせ(学習データとレシピを含む)によって、31Bの密モデルは推定LMArenaスコア(テキストのみ)1452を達成し、26BのMoEは有効4Bのアクティブパラメータのみで1441に到達します。後で見るように、多モーダル動作は、少なくとも非公式かつ主観的なテストにおいて、テキスト生成と同程度に良好です。
これらがGemma 4における主なアーキテクチャ特性です:
- ローカルのスライディングウィンドウとグローバルのフルコンテキストの注意(attention)層を交互に使用します。小さな密モデルでは512トークンのスライディングウィンドウを用い、大きなモデルでは1024トークンを用います。
- デュアルRoPEの構成:スライディング層には標準のRoPE、グローバル層には比例(proportional)のRoPEを用い、より長いコンテキストを可能にします。
- 層ごとの埋め込み(Per-Layer Embeddings: PLE):各デコーダ層に小さな残差信号を供給する、2つ目の埋め込みテーブル。
- 共有KVキャッシュ:モデルの最後のN層が、先行する層からキー・バリュー状態を再利用し、冗長なKV射影を排除します。
- 視覚(ビジョン)エンコーダ:学習済みの2D位置と多次元RoPEを使用します。元のアスペクト比を保持し、画像をいくつかの異なるトークン予算(70、140、280、560、1120)に基づいてエンコードできます。
- 音声エンコーダ:Gemma-3nのものと同じベースアーキテクチャを持つ、USMスタイルのコンフォーマー(conformer)です。
層ごとの埋め込み(PLE)
小型のGemma 4モデルにおける最も特徴的な機能の1つが、層ごとの埋め込み(Per-Layer Embeddings: PLE)です。これは以前のGemma-3nでも導入されていました。標準的なトランスフォーマーでは、各トークンは入力時に1つの埋め込みベクトルを受け取り、同じ初期表現が残差ストリームを通じてすべての層で基盤として用いられます。その結果、埋め込みがモデルに必要になり得る情報を前倒しで担うことを強制することになります。PLEは、主要な残差ストリームに並行する、より低次元の条件付け経路を追加します。各トークンについて、2つの信号を組み合わせて、すべての層に対して小さな専用ベクトルを生成します。1つはトークン同一性成分(埋め込み検索から得られるもの)で、もう1つはコンテキストに応じた成分(主要な埋め込みの学習済み射影から得られるもの)です。その後、各デコーダ層は対応するベクトルを使用します
返却形式: {"translated": "翻訳されたHTML"}r to modulate the hidden states via a lightweight residual block after attention and feed-forward. This gives each layer its own channel to receive token-specific information only when it becomes relevant, rather than requiring everything to be packed into a single upfront embedding. Because the PLE dimension is much smaller than the main hidden size, this adds meaningful per-layer specialization at modest parameter cost. For multimodal inputs (images, audio, video), PLE is computed before soft tokens are merged into the embedding sequence — since PLE relies on token IDs that are lost once multimodal features replace the placeholders. Multimodal positions use the pad token ID, effectively receiving neutral per-layer signals.共有KVキャッシュ
共有KVキャッシュは、推論時の計算とメモリの両方を削減する効率化の最適化です。モデルの最後の num_kv_shared_layers 層は、それぞれ自身のキーおよびバリューの射影を計算しません。代わりに、同じ注意(アテンション)タイプ(スライディングまたはフル)の最後の非共有層から得た K および V テンソルを 再利用します。
実際には、品質への影響は最小限ですが、長いコンテキストの生成やオンデバイス利用においては、メモリおよび計算の両面で大幅に効率的です。
マルチモーダル対応
テストの結果、Gemma 4 は標準で包括的なマルチモーダル機能をサポートしていることがわかりました。学習ミックスがどうなっていたのかは不明ですが、OCR、音声からテキストへの変換(speech-to-text)、物体検出、あるいは指さしといったタスクで成功しました。また、テキストのみの関数呼び出しとマルチモーダル関数呼び出し、推論、コード補完、そして修正もサポートしています。
ここでは、モデルサイズの異なるいくつかの推論例を示します。このノートブックで手軽に実行できます。デモをぜひ試してみて、このブログの下に共有してください!
物体検出と指さし
GUI検出
さまざまなサイズに対して、Gemma 4 を GUI 要素の検出と指さしでテストします。以下の画像とテキストプロンプトを使用します:「画像内の『レシピを表示』要素のバウンディングボックスは何ですか?」
このプロンプトに対し、モデルは検出されたバウンディングボックスを JSON 形式でネイティブに応答します。そのため、特別な指示や、文法に制約をかけた生成は不要です。座標は入力の次元に対して相対的な、画像サイズ 1000×1000 を参照していることがわかりました。
下に、わかりやすいように出力を可視化します。返ってきた JSON からバウンディングボックスを解析します:json
[
{"box_2d": [171, 75, 245, 308], "label": "view recipe element"}
]
物体検出
私たちは、日常の物体を検出するためのモデルをテストします。ここでは、自転車を検出するよう依頼し、さまざまなモデルの出力を比較します。前のケースと同様に、json からバウンディングボックスを解析し、それを画像空間の座標に変換します。
マルチモーダルの推論と関数呼び出し
Gemma 4 に、Gemini 3 で作成したページを復元するための HTML コードを書かせました。以下に、このためのコードを示します。思考を有効化し、各モデルに最大 4000 個の新しいトークンを生成させて、確実に実行できるようにしています。
推論コード
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/landing_page.png",
},
{"type": "text", "text": "このページのためのHTMLコードを書いてください。"},
],
}
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
enable_thinking=True,
).to(model.device)
output = model.generate(**inputs, max_new_tokens=4000)
input_len = inputs.input_ids.shape[-1]
generated_text_ids = output[0][input_len:]
generated_text = processor.decode(generated_text_ids, skip_special_tokens=True)
result = processor.parse_response(generated_text)
print(result["content"])
ビデオ理解
小型のGemma 4モデルは音声付きの動画を入力できる一方で、大型のモデルは音声なしの動画を入力できます。モデルは明示的に動画に対して事後学習(post-trained)されているわけではありませんが、音声あり・なしの両方で動画を理解できます。特に音声の面で強みがあります。
推論コード
messages = [
{
"role": "user",
"content": [
{"type": "video", "url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/concert.mp4"},
{"type": "text", "text": "What is happening in the video? What is the song about?"},
],
},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
load_audio_from_video=True, # disable this for larger models
).to(model.device)
output = model.generate(**inputs, max_new_tokens=200)
input_len = inputs.input_ids.shape[-1]
generated_text_ids = output[0][input_len:]
generated_text = processor.decode(generated_text_ids, skip_special_tokens=True)
print(result["content"])
| モデル | 出力 |
|---|---|
| E2B(音声について幻覚を起こしています) | 提示された動画をもとに、以下は分析です:この動画では何が起きていますか? 動画は、ライブの音楽パフォーマンスを捉えており、おそらく大規模な屋外フェスやコンサートでのものです。 * 場面: 大規模な屋外のステージが設定されています。広範な照明リグ、大きなスピーカー、そして前景に見える観客によって示されています。 * 出演者: ステージには複数のミュージシャンがいます。青いシャツと白いズボンを着たリードシンガー/ギタリストが主役のようで、アコースティックまたはエレクトリックギターを弾きながら積極的にパフォーマンスしています。背景には他のミュージシャンもおり、ドラマーやベーシストが見えます。 * 雰囲気: 照明は明るく、エネルギッシュでドラマチックです。強い青と白のスポットライト、そしてコンサートの空気を高める大量のステージフォグ/スモークが特徴です。 * 観客: 前景は観客の背中で埋まっており、観客がステージの近くにいて、パフォーマンスを熱心に見ていることがわかります。 この曲は何についてですか? 動画の下に示されている歌詞は次のとおりです。 > "I don't care 'bout street > From what I cherish > Could it's time to protest |
| E4B ✅ | この動画は、明るい照明とスモークの演出があるステージで、観客に囲まれたバンドのライブ・パフォーマンスを捉えています。バンドは演奏し、観客に向けて歌います。この曲は、現代生活の苦闘や幻滅についてのようです。特に、行き詰まりを感じていて混沌として圧倒的な世界の中で自分の居場所を見つけるのが難しいという気持ちがテーマのように見えます。歌詞には「コンクリートの街路」「破られた約束」「その日の嵐」、そして社会の圧力の中で自分を見失いがちな難しさといった要素が言及されています。 |
| 26/A4B(音声なし)✅ | この動画は、夜の屋外コンサートまたはフェスでのライブ音楽パフォーマンスを示しています。青いシャツと白いズボンを着た、1人の男性アーティストが中心に映っています。彼はアコースティックギターを弾き、大きく照らされたステージ上でマイクに向かって歌っています。演奏にはバンドが伴っており、背景や大きな映像スクリーンにもドラマーや他のミュージシャンが見えます。ステージは、雰囲気のある青い照明、スモーク、そして明るいスポットライトで満たされています。この動画は、観客からステージを見上げるカットや、パフォーマーのクローズアップが大きなスクリーンに映し出されるカットなど、さまざまな視点を捉えています。前景には観客が映っており、ショーを見ています。スクリーンの1つには「Estrella Damm」というブランド名も表示されています。 |
| 31B(音声なし)✅ | ミュージシャンがコンサート中にステージ上で演奏し、アコースティックギターを弾きながらマイクに向かって歌っています。彼は青いシャツと白いズボンを着ています。ステージは雰囲気のあるスモークに満たされ、青と白の明るいライトで照らされています。ドラマーやキーボード奏者など、他のバンドメンバーもステージに映っています。この動画は観客の視点でミュージシャンを映しており、彼に焦点を当てたカットもあれば、ステージ脇の大きなスクリーンに映るクローズアップと観客が映っているカットもあります。 |
Captioning
私たちは、キャプショニングに関してすべてのモデルをテストしました。すべてのチェックポイントは非常に良好で、複雑なシーンにおけるニュアンスを正確に捉えます。 使用している画像は次のとおりで、プロンプトは「この画像のための、1つの詳細なキャプションを書いてください。」です。
推論コード
messages = [
{
"role": "user",
"content": [
{"type": "image", "url": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/bird.png"},
{"type": "text", "text": "Write single detailed caption for this image."},
],
},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
).to(model.device)
output = model.generate(**inputs, max_new_tokens=512)
input_len = inputs.input_ids.shape[-1]
generated_text_ids = output[0][input_len:]
generated_text = processor.decode(generated_text_ids, skip_special_tokens=True)
result = processor.parse_response(generated_text)
print(result["content"])
| モデル | 出力 |
|---|---|
| E2B ✅ | 中距離ショットでは、傷んだカモメが石の台座の上に止まっており、賑やかなヨーロッパの広場のように見えます。右側のフレームを、装飾的な柱や建築の細部を備えた、立派な古典様式の建物が支配しています。背景には、中景に低く淡い色の建物が横に伸びており、緑の植生が添えられていて、さらにテラコッタ色の屋根を持つ建物など、ほかの構造物の存在もかすかに見えます。前景には、近代的なバス停またはシェルターの一部が見え、ルートを示す看板があります。全体のシーンは、淡い空の下で明るい日差しに照らされています。 |
| E4B ✅ | 1羽のカモメが、灰色の石の台座の上に止まっています。場所は賑やかなヨーロッパの広場で、右側のフレームを古典的な建物の歴史的な壮麗さが支配しており、明るいもやがかった空の下で背景に見える、より近代的な低層の建築と対比されています。 |
| 26B/A4B ✅ | フルショットでは、イタリア・ベネチアで白と茶色のカモメが灰色の柱の上に止まっています。カモメは左を向いており、くちばしがフレーム端に向けられています。後ろには、淡い灰色の2階建ての建物があり、いくつかの濃い長方形の窓があります。カモメの右側には、柱と精巧な彫刻のある大きな白い建物があります。空は澄んだ淡い青です。照明は明るく均一で、昼間であることを示唆しています。 |
| 31B ✅ | 高い位置からの中距離ショットで、イタリア・ベネチアにある灰色のコンクリートの支柱の上に、白と灰色のカモメが止まっています。カモメは左を向き、体はわずかにカメラの方へ傾けられています。白い頭、首、胸が、灰色の翼と背中と対照的です。カモメのオレンジ色のくちばしは少し開いています。支柱は、風化した質感のある淡い灰色のコンクリート製の円柱です。背景にはいくつかの建物があります。左側には、細かな長方形の窓が並ぶ長い低い白い建物があります。中央には緑の木々のかたまりがあります。右側には、タイル張りの屋根といくつかの小さな長方形の窓を備えた赤い建物があります。さらに右には、複数の柱と彫刻のある大きく豪華な白い石造りの建物があります。空は淡い青で、光は明るく澄んでいます。画面左下には、「Ferrovia」という文字が黒で印刷された黄色いバスがあります。背景には数人が歩いていますが、小さく、ピントが合っていません。 |
Audio Question Answering
これらのモデルは、音声(オーディオ)に含まれる発話に関する質問に答えるよう訓練されています。音楽や、発話ではない音は訓練データに含まれていません。
推論コード
messages = [
{
"role": "user",
"content": [
{"type": "audio", "url": "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"},
{"type": "text", "text": "Can you describe this audio in detail?"},
],
},
]
返却形式: {"translated": "翻訳されたHTML"}
| Model | Output |
|---|---|
| E2B | この音声は個人的な回顧です。話し手は、シカゴで行った国家への最終的な別れの挨拶について語っています。彼は、直接会ったことがなく、挨拶すらしたことがないとしても、リビングルーム、学校、農場、工場の作業場、食堂、そして軍の前線拠点など、さまざまな場でのこれらのやり取りが、自分を支え、生き続けさせてくれたのだと述べています。 |
| E4B | この音声は、話し手がシカゴから国家への別れの挨拶を行うスピーチ抜粋です。話し手は政権在任中を振り返り、リビングルーム、学校、農場、工場、食堂、軍の前線拠点など、さまざまな場でアメリカの人々と交わした会話への感謝を表します。語り口は、振り返りと感謝に満ちており、こうしたやり取りが政治の歩みにおいて重要であることを強調しています。 |
文字起こしを行いたい場合の例を示します:
Inference code
messages = [
{
"role": "user",
"content": [
{"type": "audio", "url": "https://huggingface.co/datasets/hf-internal-testing/dummy-audio-samples/resolve/main/obama_first_45_secs.mp3"},
{"type": "text", "text": "音声を文字起こししますか?"},
],
},
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
).to(model.device)
output = model.generate(
**inputs,
max_new_tokens=1000,
do_sample=False,
)
print(processor.decode(output[0], skip_special_tokens=True))
| Model | Output |
|---|---|
| E2B | 今週、私はシカゴへ旅し、私の最終的な国家への別れの挨拶を行いました。これは、私の前にいた大統領たちが踏襲してきた伝統に従うものです。目が合うか、決して意見が一致しなかったとしても、あなたに感謝を伝える絶好の機会でした。あなたと私の会話は、アメリカの人々との会話であり、リビングルームや学校、農場、工場の現場、食堂、そして遠く離れた軍の前線拠点などで交わしたものです。これらの会話こそが、私を誠実でいさせてくれました。 |
| E4B | 今週、私はシカゴへ旅し、私の前にいた大統領たちが踏襲してきた伝統に従って、国家への私の最終的な別れの挨拶を行いました。それは、感謝を伝える機会でした。私たちが目と目を合わせていたことがあっても、あるいはまったく同意することがほとんどなかったとしても、あなたであるアメリカの人々との私の会話は、リビングルームや学校、農場、工場の作業場、食堂、そして遠く離れた軍の前線拠点における会話であり、これらすべてのやり取りこそが私を誠実でいさせてくれました。 |
マルチモーダル・ファンクション・コーリング
モデルをテストするために、画像に表示されている場所の天気を取得するよう依頼します。
Inference code
import re
WEATHER_TOOL = {
"type": "function",
"function": {
"name": "get_weather",
"description": "特定の場所の現在の天気を取得します。",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "都市名"},
},
"required": ["city"],
},
},
}
tools = [WEATHER_TOOL]
messages = [
{"role": "user", "content": [
{"type": "image", "image": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/thailand.jpg"},
{"type": "text", "text": "この画像の都市はどこですか?そこですぐ今の天気を確認してください。"},
]},
]
inputs = processor.apply_chat_template(
messages,
tools=[WEATHER_TOOL],
tokenize=True,
return_dict=True,
return_tensors="pt",
add_generation_prompt=True,
enable_thinking=True,
).to(model.device)
output = model.generate(**inputs, max_new_tokens=1000)
input_len = inputs.input_ids.shape[-1
返却形式: {"translated": "翻訳されたHTML"}generated_text_ids = output[0][input_len:]
generated_text = processor.decode(generated_text_ids, skip_special_tokens=True)
result = processor.parse_response(generated_text)
print(result["content"])
| Model | Output |
|---|---|
| E2B | リクエストの分析: ユーザーは画像を提供し、2つの質問をしました:
* 「この画像の都市はどこですか?」 * 「そこはいまの天気はどうですか?」
2. 画像の分析: 画像には、寺院建築に特徴的な、大きく装飾的で背の高い構造物が写っています。スタイルから判断すると、おそらく東南アジア(の地域)のものです。著名なランドマークのように見えます。 3. ランドマーク/場所の特定(内部知識/視覚的手がかり): この構造は、タイのバンコクなどの場所で見られるチェディ/ストゥーパに強く似ています(例:ワット・アルンのような構造)。
4. 都市の特定: 視覚的な証拠から、この場所は非常に高い確率でタイのバンコクであると考えられます。
5. 利用可能なツールの確認: 利用可能なツールは get_weather(city: STRING) です。 6. **計画を立てる:**
* 手順1: 画像から都市を特定する(バンコク)。
* 手順2: 特定した都市を使って get_weather ツールを使用する。
7. ツール呼び出しの構築: get_weather(city="Bangkok")
8. 応答の生成: モデルはまず特定した都市を述べ、その後ツールを呼び出して天気を取得するべきです。(自己修正: モデルは、外部情報が必要な場合、正しい形式で必ずツールを呼び出さなければなりません。)call:get_weather{city:Bangkok} |
| E4B | '1. リクエストの分析: ユーザーは画像を提供しており、2つのことを尋ねています:
a. 画像内の都市を特定する。
b. その都市のいまの天気を確認する。
2. 画像の分析: 画像には非常に特徴的で、装飾が施された塔/尖塔状の構造が写っています。これはタイの建築に特徴的です(具体的には、チェディやプランのようなもの)。
3. 都市の特定(内部知識/視覚的認識): 建築様式に基づくと、その構造はバンコクのワット・アルンのようなタイの著名な寺院によく似ています。
4. ツール利用可能性の評価: 利用可能なツールは1つです:get_weather(city: STRING)。このツールは入力として都市名が必要です。
5. **計画の作成:**
a. get_weather ツールを使うために都市名が必要です。
b. まず画像から都市を特定する必要があります。
c. 私の内部知識ではバンコクだと示唆されるため、その前提で進めますが、画像だけで場所を確実に証明できないことは認めなければなりません。
6. 手順1の実行(都市の特定): 建築の視覚的証拠から、都市はバンコクだと仮定します。
7. 手順2の実行(ツール呼び出しの生成): get_weather ツールを、「Bangkok」を city 引数として使って呼び出します。
8. 応答の構築: JSON形式で適切なツール呼び出しを生成します。', 'answer': '<|tool_call>call:get_weather{city:<|"|>Bangkok<|"|>}<tool_call|>' |
| 31B | ユーザーは画像内の都市と、そこにおける現在の天気を知りたいようです。 1. 画像の分析: 画像には、タイの寺院建築に特徴的な、装飾的で尖塔のような構造(プラン)が写っています。具体的には、タイ・バンコクのワット・プラ・ケーオ(エメラルド寺院)やワット・ポーのプランに似ています。様式はバンコクの王室寺院群に非常に独特です。 2. 都市の特定: 建築様式に基づき、都市はバンコクです。 3. 天気の確認: city="Bangkok" を指定して get_weather ツールを呼び出す必要があります。call:get_weather{city:Bangkok} |
| 26/A4B | 画像には、タイの仏教寺院建築に典型的な、背の高い装飾的な塔(プラン)がいくつか写っています。具体的には、タイ・バンコクの大宮殿やワット・プラ・ケーオ内の構造に見えます。様式ははっきりとタイらしいです。特定の塔を見て確認します。これらは非常に象徴的です。
2. 場所の確認: 画像にはバンコクの大宮殿コンプレックスの要素が写っています。
3. 天気情報の取得: 都市がバンコクだと特定できたら、city='Bangkok' を指定して get_weather ツールを使います。call:get_weather{city:Bangkok} |
どこでもデプロイ
Gemma 4 は、多くのオープンソースの推論エンジンに対する day-0 のサポートを備えており、ツール呼び出しやエージェントに最適です。また、多くのハードウェアバックエンドで動作できる ONNX チェックポイントも提供しており、エッジデバイスやブラウザでのユースケースを可能にします!
transformers
Gemma 4 は、最初から get-go での first-class な transformers サポートを備えています。この統合により、モデルを bitsandbytes、PEFT、TRL のような他のライブラリと一緒に使うことができます。transformers の最新版をインストールするようにしてください。
pip install -U transformers
小さな Gemma 4 モデルで推論を行う最も簡単な方法は、any-to-any パイプラインを使うことです。次のように初期化できます。
from transformers import pipeline
pipe = pipeline("any-to-any", model="google/gemma-4-e2b-it")
次に、以下のように画像とテキストを渡せます。
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/thailand.jpg",
},
{"type": "text", "text": "ここへの旅行のアドバイスはありますか?"},
],
}
]
output = pipe(messages, max_new_tokens=100, return_full_text=False)
output[0]["generated_text"]
# 画像から判断すると、壮麗で装飾の施された**仏教寺院または仏塔**が写っているように見えます。おそらくタイ、ミャンマー、カンボジアなどの東南アジアのどこかでしょう。以下に、一般的な旅行アドバイスをいくつか挙げます。.
動画で推論する場合は、load_audio_from_video 引数を使って音声トラックを含められます。
messages = [
{
"role": "user",
"content": [
{
"type": "video",
"image": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/rockets.mp4",
},
{"type": "text", "text": "この動画では何が起きていますか?"},
],
}
]
pipe(messages, load_audio_from_video=True)
さらに一段下のレベルでは、AutoModelForMultimodalLM クラスを使って Gemma 4 を読み込めます。特にファインチューニングに便利です。組み込みのチャットテンプレートが入力のフォーマットを正しく処理してくれますので、プロンプトを手動で組み立てる際の微妙なミスを防ぐために、必ずそれを使ってください。
推論コード
from transformers import AutoModelForMultimodalLM, AutoProcessor
model = AutoModelForMultimodalLM.from_pretrained("google/gemma-4-E2B-it", device_map="auto")
processor = AutoProcessor.from_pretrained("google/gemma-4-E2B-it")
messages = [
{
"role": "user",
"content": [
{
"type": "video",
"image": "https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/rockets.mp4",
},
{"type": "text", "text": "この動画では何が起きていますか?"},
],
}
]
inputs = processor.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**inputs, max_new_tokens=128)
generated_ids_trimmed = [
out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
]
output_text = processor.batch_decode(
generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
)
print(output_text)
Llama.cpp
Gemma 4 モデルは最初から、llama.cpp で画像+テキストに対応しています!これにより、Gemma 4 をあなたのお気に入りのローカルアプリすべてで使えるようになります。たとえば llama-cpp server、lmstudio、Jan などに加えて、Metal や CUDA など多くのバックエンドで動作する Pi のようなコーディングエージェントでも利用できます。
以下のように llama-cpp をインストールできます。
brew install llama.cpp # MacOS
winget install llama.cpp # Windows
次に、OpenAI API と互換性のあるサーバーを起動します。コマンド末尾の quantization(量子化)スキームを、希望する精度に置き換えてください。
llama-server -hf ggml-org/gemma-4-E2B-it-GGUF
llama.cpp をさまざまなコーディングエージェントやローカルアプリと組み合わせるための その他のオプションはこちら のリンクを確認してください。このコレクション にあるすべての GGUF チェックポイントを見つけられます。
ローカルエージェントを接続する
新しいモデルが、openclaw, hermes, pi, open code のようなエージェントと一緒にローカルで動作するように調整しました。すべて llama.cpp のおかげです!以下を実行して、すぐに Gemma 4 を試してください。
まず、ローカルサーバーを起動します:
llama-server -hf ggml-org/gemma-4-26b-a4b-it-GGUF:Q4_K_M
hermes の場合:
hermes model
openclaw の場合:
openclaw onboard
pi の場合は、~/.pi/agent/models.json を定義します:
{
"providers": {
"llama-cpp": {
"baseUrl": "http://localhost:8080/v1",
"api": "openai-completions",
"apiKey": "none",
"models": [
{
"id": "ggml-org-gemma-4-26b-4b-gguf"
}
]
}
}
}
open code の場合は、~/.config/opencode/opencode.json を定義します:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"llama.cpp": {
"npm": "@ai-sdk/openai-compatible",
"name": "llama-server (local)",
"options": {
"baseURL": "http://127.0.0.1:8080/v1"
},
"models": {
"gemma-4-26b-4b-it": {
"name": "Gemma 4 (local)",
"limit": {
"context": 128000,
"output": 8192
}
}
}
}
}
}
transformers.js
transformers.js により、Gemma 4 をブラウザ内で直接実行できます。テキストのみ、画像&amp;テキスト、音声&amp;テキストの推論を詳しく確認するには、こちら のモデルカードを参照してください。また、モデルをテストできるデモも こちら で用意しました。




















