Gemma 4 VLA デモ(Jetson Orin Nano Super)
あなたの発話 → Parakeet STT → Gemma 4 → [必要ならWebcam] → Kokoro TTS → スピーカー
SPACEを押して録音し、もう一度SPACEを押して停止します。これはシンプルなVLAです。モデルが、あなたが尋ねた内容の文脈に基づいて自分で行動を判断します。キーワードトリガーも、ハードコードされたロジックもありません。あなたの質問にはGemmaが目を開ける必要がある場合、彼女は写真を撮るかどうかを判断し、解釈して、その文脈を踏まえて答えます。彼女は画像を説明しているのではなく、見た内容を使って、あなたの実際の質問に答えています。
そして正直なところ? Jetson Orin Nanoでこれが動くのは、かなりすごいです。:)
コードを取得
このチュートリアルの完全なスクリプトはGitHubにあります。私のGoogle_Gemmaリポジトリ内で、Gemma 2のデモの隣に置いています:
github.com/asierarranz/Google_Gemma
次のどちらかで入手してください(どちらか一つ選択):
# オプション1:リポジトリ全体をクローン
git clone https://github.com/asierarranz/Google_Gemma.git
cd Google_Gemma/Gemma4
# オプション2:スクリプトだけダウンロード
wget https://raw.githubusercontent.com/asierarranz/Google_Gemma/main/Gemma4/Gemma4_vla.py
この1つのファイル(Gemma4_vla.py)だけで十分です。初回実行時に、STT/TTSモデルと音声アセットをHugging Faceから取り込みます。
ハードウェア
使用したもの:
- NVIDIA Jetson Orin Nano Super(8GB)
- Logitech C920ウェブカメラ(マイク内蔵)
- USBスピーカー
- USBキーボード(SPACEを押すため)
これらの正確なデバイスに限定されません。Linuxが認識する任意のWebカメラ、USBマイク、USBスピーカーで動作するはずです。
返却形式: {"translated": "翻訳されたHTML"}Step 1: システムパッケージ
新しいJetsonなら、まずは基本をインストールしましょう:
sudo apt update
sudo apt install -y \
git build-essential cmake curl wget pkg-config \
python3-pip python3-venv python3-dev \
alsa-utils pulseaudio-utils v4l-utils psmisc \
ffmpeg libsndfile1
build-essential と cmake は、ネイティブな llama.cpp の手順(手順4のオプションA)に進む場合にのみ必要です。それ以外は、音声・Webカメラ・Python のためです。
Step 2: Python 環境
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install opencv-python-headless onnx_asr kokoro-onnx soundfile huggingface-hub numpy
Step 3: RAM を解放する(任意だが推奨)
注意:この手順は必須というわけではないかもしれません。ただ、かなり高機能なモデルで、この 8GB のボードをかなり強く押していくので、余裕を持たせておくと体験全体がよりスムーズになります。特に、それ以前に Docker やその他の重いものをいじっていた場合は効果が出ます。
以下は、私の環境でうまく動いたコマンドだけです。役に立ちそうなら使ってください。
スワップを少し追加する
スワップは推論を速くするわけではありませんが、モデル読み込み中のセーフティネットとして働くため、最悪のタイミングで OOM によってプロセスが強制終了されるのを防げます。
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
メモリを食い潰すプロセスを停止する
sudo systemctl stop docker 2>/dev/null || true
sudo systemctl stop containerd 2>/dev/null || true
pkill -f tracker-miner-fs-3 || true
pkill -f gnome-software || true
free -h
ブラウザのタブ、IDEのウィンドウ、必要ないものはすべて閉じてください。すべての MB が重要です。
手順4で Docker のルートを選ぶ場合は、もちろんここで Docker を停止しないでください。必要になるからです。それでも、それ以外は停止して構いません。
RAMがまだきつい?
私たちのテスト結果では、上で行ったクリーンアップを済ませれば、Q4_K_M(ネイティブビルド)とQ4_K_S(Docker)は8 GBのボード上で快適に動作します。ですが、どうしても止められない他のプロセスがあってメモリがまだきつい場合は、1段階下げて同じモデルのQ3量子化に落としてください。賢さは少し下がりますが、明確に軽くなります。手順4のところでファイル名を入れ替えるだけです:
gemma-4-E2B-it-Q3_K_M.gguf # Q4_K_Mの代わりに
とはいえ、可能なら本当にQ4_K_Mでいきましょう。ちょうど良い(ベストな)ところです。
手順4:Gemma 4を提供(起動)
デモを起動する前に、Gemma 4で動作する稼働中のllama-serverが必要です。Jetson上でllama.cppをネイティブにビルドします。そうすると、デモに必要なVLAのビジョン・プロジェクタに対して最良のパフォーマンスと完全な制御が得られます。
llama.cppをビルド
cd ~
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
cmake -B build \
-DGGML_CUDA=ON \
-DCMAKE_CUDA_ARCHITECTURES="87" \
-DGGML_NATIVE=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j4
モデルとビジョン・プロジェクタをダウンロード
mkdir -p ~/models && cd ~/models
wget -O gemma-4-E2B-it-Q4_K_M.gguf \
https://huggingface.co/unsloth/gemma-4-E2B-it-GGUF/resolve/main/gemma-4-E2B-it-Q4_K_M.gguf
wget -O mmproj-gemma4-e2b-f16.gguf \
https://huggingface.co/ggml-org/gemma-4-E2B-it-GGUF/resolve/main/mmproj-gemma4-e2b-f16.gguf
mmprojファイルはビジョン・プロジェクタです。これがないとGemmaは見えないので、スキップしないでください。
サーバを起動
~/llama.cpp/build/bin/llama-server \
-m ~/models/gemma-4-E2B-it-Q4_K_M.gguf \
--mmproj ~/models/mmproj-gemma4-e2b-f16.gguf \
-c 2048 \
--image-min-tokens 70 --image-max-tokens 70 \
--ubatch-size 512 --batch-size 512 \
--host 0.0.0.0 --port 8080 \
-ngl 99 --flash-attn on \
--no-mmproj-offload --jinja -np 1
触れておく価値があるフラグが1つあります:-ngl 99は、llama-serverに対して、モデルの全レイヤーをGPUに載せるよう指示します(99は「モデルが持つレイヤー数と同じだけ」という意味です)。もしメモリの問題に遭遇したことがあるなら、この数値を下げることで、より少ないレイヤーだけをオフロードして減らせます。
起動していることを確認してください
別のターミナルから:
curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"gemma4","messages":[{"role":"user","content":"Hi!"}],"max_tokens":32}' \
| python3 -m json.tool
JSONが返ってくればOKです。
ステップ5:マイク、スピーカー、Webカメラを見つける
マイク
arecord -l
USBマイクを探します。今回の場合はC920がplughw:3,0として表示されました。
スピーカー
pactl list short sinks
これはPulseAudioのスピーカー(sink)を一覧表示します。スピーカーに合うものを選んでください。alsa_output.usb-...のような、見た目がひどい長い名前になります。私の場合はalsa_output.usb-Generic_USB2.0_Device_20130100ph0-00.analog-stereoでしたが、あなたの環境では異なるはずです。
Webカメラ
v4l2-ctl --list-devices
通常はインデックス0(つまり/dev/video0)です。
クイックテスト
export MIC_DEVICE="plughw:3,0"
export SPK_DEVICE="alsa_output.usb-Generic_USB2.0_Device_20130100ph0-00.analog-stereo"
arecord -D "$MIC_DEVICE" -f S16_LE -r 16000 -c 1 -d 3 /tmp/test.wav
paplay --device="$SPK_DEVICE" /tmp/test.wav
自分の声が聞こえればOKです。
ステップ6:デモを実行する
ステップ4のサーバーが動いていることを確認してから、次を実行します:
source .venv/bin/activate
export MIC_DEVICE="plughw:3,0"
export SPK_DEVICE="alsa_output.usb-Generic_USB2.0_Device_20130100ph0-00.analog-stereo"
export WEBCAM=0
export VOICE="af_jessica"
python3 Gemma4_vla.py
初回起動時に、スクリプトは Parakeet STT、Kokoro TTS をダウンロードし、音声プロンプトの WAV を生成します。1分ほどかかります。その後、すぐに使えるようになります。
- SPACE → 録音を開始
- 質問を話す
- SPACE → 録音を停止
音声のセットアップをスキップして、LLM パスを直接テストしたい場合は、テキスト専用モードもあります:
python3 Gemma4_vla.py --text
声(ボイス)を変更する
Kokoro には多くの声が用意されています。次で切り替えます:
export VOICE="am_puck"
python3 Gemma4_vla.py
おすすめのもの:af_jessica、af_nova、am_puck、bf_emma、am_onyx。
仕組み
このスクリプトは、Gemma 4 に対してちょうど1つのツールを公開します:
{
"name": "look_and_answer",
"description": "Take a photo with the webcam and analyze what is visible."
}
質問すると:
- あなたの音声がローカルで文字起こしされます(Parakeet STT)
- Gemma はテキストに加えてツール定義を受け取ります
- 質問が視覚を必要とする場合、彼女は
look_and_answerを呼び出します。スクリプトはウェブカメラのフレームを取得し、それを返します - Gemma が回答し、Kokoro がそれを音声で読み上げます
キーワードのマッチングはありません。モデルが「見る必要があるかどうか」を判断します。これが VLA の部分です。
llama-server の --jinja フラグがこれを可能にしており、Gemma のネイティブなツール呼び出しサポートを有効化します。
トラブルシューティング
サーバーがメモリ不足になったら、手順3のクリーンアップをもう一度行ってください。すべてを閉じてください。このモデルは8 GBに収まりますが、きちんと整理する必要があります。
音が出ない場合は、pactl list short sinksを確認し、SPK_DEVICEが実在するシンクと一致していることを確かめてください。
マイクが無音を録音する場合は、arecord -lで二重に確認し、その後手動で録音テストをしてください。
最初の実行が遅いのは正常です。モデルをダウンロードし、音声プロンプトを生成しています。2回目の実行は速くなります。
環境変数
| 変数 | デフォルト | 説明 |
|---|---|---|
LLAMA_URL |
http://127.0.0.1:8080/v1/chat/completions |
llama-server のエンドポイント |
MIC_DEVICE |
plughw:3,0 |
ALSA のキャプチャデバイス |
SPK_DEVICE |
alsa_output.usb-...analog-stereo |
再生用の PulseAudio シンク |
WEBCAM |
0 |
Webカメラのインデックス(/dev/videoN) |
VOICE |
af_jessica |
Kokoro TTS の音声 |
ボーナス:Gemma 4をテキストモードで試すだけなら?
完全なVLAデモには興味がなく、何もビルドせずにJetson上でGemma 4をちょっと触ってみたいだけなら、Jetson AI LabがOrin向けにllama.cppを事前コンパイルした、すぐ使えるDockerイメージを用意しています:
sudo docker run -it --rm --pull always \
--runtime=nvidia --network host \
-v $HOME/.cache/huggingface:/root/.cache/huggingface \
ghcr.io/nvidia-ai-iot/llama_cpp:latest-jetson-orin \
llama-server -hf unsloth/gemma-4-E2B-it-GGUF:Q4_K_S
1行で、コンパイル不要です。そして-hfは初回実行時にHugging FaceからGGUFを取得します。http://localhost:8080を、OpenAI互換クライアントなら何でも使ってアクセスして、チャットしてください。
注意:このDockerの手順はテキストのみです。視覚プロジェクターは読み込まれないため、上のVLAデモでは動きません。ウェブカメラ体験をフルで楽しみたい場合は、手順4のネイティブビルドを使ってください。
このチュートリアルを楽しんでいただけたなら幸いです! 質問やアイデアがあれば、お気軽に連絡してください。:)
Asier Arranz | NVIDIA


