Tổng quan hệ thống, tối ưu và cách triển khai
Chạy một mô hình Vision-Language-Action (VLA) hoàn toàn cục bộ trên thiết bị edge 8GB nghe có vẻ hơi quá sức, nhưng demo này cho thấy điều đó đã bắt đầu khả thi nếu tối ưu đúng chỗ. Trọng tâm ở đây không phải là một chatbot gắn thêm webcam cho có, mà là một hệ thống có thể:
- nghe người dùng qua micro,
- hiểu yêu cầu bằng mô hình ngôn ngữ,
- tự quyết định khi nào cần nhìn qua camera,
- rồi trả lời lại bằng giọng nói.
Điểm đáng giá nhất của demo Gemma 4 VLA trên Jetson Orin Nano Super 8GB nằm ở chỗ: vision không bị hardcode bằng if/else hoặc keyword trigger. Người dùng không cần nói kiểu “hãy nhìn camera” hay “check webcam giúp tôi”. Thay vào đó, mô hình được cung cấp một tool duy nhất và tự suy luận xem câu hỏi có cần truy cập hình ảnh hay không.
Tóm tắt nhanh
- Thiết bị: NVIDIA Jetson Orin Nano Super 8GB
-
Mô hình trung tâm: Gemma 4 GGUF chạy bằng
llama.cpp/llama-server - STT: Parakeet
- TTS: Kokoro ONNX
-
Vision: webcam +
mmproj -
Cơ chế quyết định hành động: native tool calling với
--jinja -
Quantization khuyến nghị:
Q4_K_M, fallbackQ3_K_M - Mục tiêu thực tế: chạy local-first, giảm phụ thuộc cloud, tối ưu RAM trên edge 8GB
Vì sao demo này đáng chú ý?
Trong nhiều voice assistant tự chạy local hiện nay, luồng xử lý thường dừng ở mức:
- Speech-to-text
- LLM trả lời bằng text
- Text-to-speech đọc lại
Nếu muốn thêm camera, phần lớn hệ thống sẽ rơi vào một trong hai cách:
- gọi vision mọi lúc, gây lãng phí compute, bộ nhớ và image tokens;
- chỉ gọi vision khi có keyword, khiến trải nghiệm kém tự nhiên.
Demo này đi theo hướng hợp lý hơn: model là tác nhân ra quyết định, còn webcam chỉ là một tool có thể được kích hoạt khi cần.
Đây là VLA chứ không chỉ là voice assistant có webcam
Khác biệt kỹ thuật nằm ở quyền quyết định sử dụng thị giác.
Hệ thống chỉ expose một tool cho model:
{
"name": "look_and_answer",
"description": "Take a photo with the webcam and analyze what is visible."
}
Gemma 4 nhận:
- câu hỏi dạng text,
- định nghĩa tool,
- và khả năng gọi tool theo cơ chế native tool calling.
Nếu mô hình thấy rằng câu hỏi như:
- “Trên bàn có gì?”
- “Cái cốc trước mặt mình màu gì?”
- “Camera đang thấy gì?”
thì nó sẽ chủ động gọi webcam.
Điểm này nghe đơn giản, nhưng về mặt thiết kế agent, đây là bước tiến rõ rệt so với kiểu “chat với ảnh”. Nó biến mô hình từ một thành phần trả lời tĩnh thành một tác nhân có quyền hành động tối thiểu.
Luồng xử lý end-to-end từ giọng nói đến phản hồi
Pipeline tổng thể khá gọn:
You speak → Parakeet STT → Gemma 4 → [Webcam if needed] → Kokoro TTS → Speaker
Các lớp chức năng chính:
- STT layer: Parakeet
-
LLM/VLM layer: Gemma 4 chạy qua
llama-server -
Tool-calling layer: tool
look_and_answer - Vision input layer: webcam frame
- TTS layer: Kokoro ONNX
- I/O layer: ALSA / PulseAudio / V4L2
Vai trò của từng thành phần
Parakeet STT
- chuyển giọng nói thành văn bản;
- cung cấp đầu vào cho Gemma 4;
- tách biệt hoàn toàn với phần suy luận multimodal.
Gemma 4
- hiểu yêu cầu;
- quyết định có cần vision hay không;
- sinh câu trả lời cuối cùng;
- điều phối việc gọi tool.
Kokoro TTS
- đọc phản hồi ra loa;
- chạy qua ONNX nên phù hợp với thiết bị edge nhỏ gọn;
- có thể thay voice nhanh qua biến môi trường.
Cách chia này hợp lý vì:
- STT và TTS có thể thay thế độc lập;
- phần LLM/VLM giữ vai trò “bộ não” trung tâm;
- việc debug dễ hơn nhiều so với một stack monolithic.
Kiến trúc kỹ thuật: llama-server, mmproj và --jinja
Đây là phần quan trọng nhất nếu nhìn demo dưới góc độ hệ thống.
Để Gemma 4 thực sự xử lý được ảnh và tool calling, backend llama-server cần đủ ba thành phần:
- model GGUF của Gemma 4
- vision projector (
mmproj) -
--jinjađể bật template và native tool calling đúng cách
Nếu thiếu một trong ba:
- thiếu GGUF: không có model để chạy;
- thiếu mmproj: nhánh xử lý ảnh không hoạt động đúng;
- thiếu
--jinja: tool calling native không hoạt động như kỳ vọng.
Nói ngắn gọn:
-
llama-serverlà cổng API tương thích kiểu OpenAI; -
mmprojánh xạ embedding hình ảnh vào không gian biểu diễn của model; -
--jinjagiúp model dùng đúng chat template và cơ chế tool calling gốc.
Vì sao cách ghép này phù hợp với edge inference?
Với phần cứng hạn chế như Jetson 8GB, điều quan trọng không chỉ là “có chạy được hay không”, mà là:
- quản lý bộ nhớ chặt chẽ,
- giảm tầng phụ thuộc không cần thiết,
- kiểm soát được latency,
- và dễ debug khi có lỗi I/O, audio hoặc multimodal.
So với nhiều framework agent nặng hơn, llama.cpp có lợi thế thực dụng hơn cho bài toán này: ít overhead, kiểm soát memory tốt hơn, triển khai sát phần cứng hơn.
Yêu cầu phần cứng, giới hạn RAM và chiến lược quantization
Nếu chỉ đọc tiêu đề “Gemma 4 trên Jetson Orin Nano Super 8GB”, nhiều người sẽ nghĩ đây là một màn biểu diễn. Thực tế là chạy được, nhưng headroom RAM không nhiều.
Cấu hình phần cứng tối thiểu đã được kiểm chứng
Thiết bị mẫu:
- Board: NVIDIA Jetson Orin Nano Super
- RAM: 8 GB
- Webcam: Logitech C920
- Mic: micro webcam hoặc USB mic
- Speaker: USB speaker
- Input trigger: phím SPACE trên keyboard
Điểm hay là demo không khóa cứng vào đúng bộ thiết bị này. Miễn Linux nhận được thiết bị qua các công cụ quen thuộc như:
arecordpactlv4l2-ctl
thì có thể thay bằng phần cứng khác.
Vì sao Q4 là điểm cân bằng hợp lý trên Jetson 8GB
Với Jetson 8GB, gần như bắt buộc phải dùng GGUF quantized model.
Khuyến nghị thực tế:
-
Q4_K_M: lựa chọn cân bằng cho bản native multimodal -
Q4_K_S: phù hợp hơn cho Docker text-only -
Q3_K_M: phương án fallback khi thiếu RAM
Lý do Q4 thường là điểm cân bằng tốt:
- chất lượng suy luận ổn hơn Q3;
- chi phí bộ nhớ thấp hơn đáng kể so với quant nặng hơn;
- đủ thực dụng để chạy multimodal trên edge.
Nếu so với các mô hình lớn hơn hoặc kém tối ưu hơn cho GGUF, Gemma 4 ở mức quant này có lợi thế rõ: chạy được thật trên phần cứng nhỏ, không chỉ dừng ở benchmark hoặc text-only demo.
Khi nào nên hạ xuống Q3?
Bạn nên cân nhắc Q3_K_M nếu gặp một trong các tình huống sau:
- load model bị OOM;
- còn đang chạy song song:
- Docker,
- browser,
- IDE,
- indexing services;
- swap đã bật nhưng hệ thống vẫn chậm hoặc thiếu headroom;
- cần ưu tiên ổn định hơn chất lượng suy luận tối đa.
Fallback quant nhẹ hơn:
gemma-4-E2B-it-Q3_K_M.gguf # instead of Q4_K_M
Chuẩn bị môi trường chạy trên Jetson
Phần chuẩn bị môi trường quyết định phần lớn khả năng “demo chạy ngay” hay “vật lộn vài tiếng với OOM và lỗi thiết bị”. Với Jetson, bài học quen thuộc là: đừng xem nhẹ bộ nhớ và I/O stack.
1) Cài đặt package hệ thống
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
Các gói này phục vụ cho:
- build
llama.cpp, - Python runtime,
- audio input/output,
- webcam discovery,
- xử lý file âm thanh.
2) Tạo Python virtual environment và cài dependency cho STT/TTS
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
Các dependency đáng chú ý:
-
opencv-python-headless: capture frame từ webcam -
onnx_asr: STT pipeline -
kokoro-onnx: TTS chạy cục bộ -
soundfile: xử lý audio -
huggingface-hub: hỗ trợ tải tài nguyên -
numpy: xử lý mảng cơ bản
3) Dọn RAM, thêm swap và giảm nguy cơ OOM
Trên máy 8GB, nếu để mọi dịch vụ nền chạy tự do thì rất dễ thất bại ngay từ bước load model. Vì vậy cần tạo thêm headroom.
Tạo swap 8GB:
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
Dọn RAM trước khi chạy:
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
Đây là một điểm rất “edge engineering”: bài toán không chỉ là AI model, mà là memory budgeting.
Những thứ nên tránh chạy song song:
- Docker containers không liên quan
- trình duyệt web
- VS Code / IDE
- dịch vụ index file
- desktop app nặng
Triển khai backend Gemma 4 với llama.cpp
Nếu mục tiêu là VLA đầy đủ với webcam + tool calling, con đường thực tế nhất là build native llama.cpp.
Build llama.cpp native cho Jetson Orin
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
Ý nghĩa của các lựa chọn build:
-
GGML_CUDA=ON: bật tăng tốc CUDA cho inference -
DCMAKE_CUDA_ARCHITECTURES="87": khớp kiến trúc GPU của Orin -
GGML_NATIVE=ON: tối ưu cho máy hiện tại - Release build: ưu tiên hiệu năng và giảm overhead debug
Tải model GGUF và vision projector
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
Hai file cốt lõi:
-
model:
gemma-4-E2B-it-Q4_K_M.gguf -
vision projector:
mmproj-gemma4-e2b-f16.gguf
Nếu thiếu mmproj, bạn sẽ không có multimodal path thực sự.
Khởi chạy llama-server với cấu hình tối ưu cho multimodal inference
~/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
Đây là cấu hình đáng giữ nguyên khi chạy trên Jetson 8GB vì nó phản ánh đúng tư duy tối ưu cho edge multimodal:
-
-ngl 99: offload tối đa layer lên GPU -
--flash-attn on: giảm overhead attention, cải thiện tốc độ -
--no-mmproj-offload: giữ projector theo cấu hình phù hợp với setup này -
--image-min-tokens 70 --image-max-tokens 70: cố định token budget cho ảnh -
--ubatch-size 512 --batch-size 512: cân bằng throughput và giới hạn RAM -
-c 2048: context vừa đủ cho demo và tool calling -
--jinja: bật native tool calling -
-np 1: số slot hợp lý cho thiết bị nhỏ
Kiểm tra OpenAI-compatible endpoint trước khi chạy demo
Trước khi nối STT, webcam và TTS vào cùng một loop, hãy xác minh backend LLM hoạt động ổn định trước.
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
Nếu endpoint này chưa ổn, đừng đi tiếp. Trong các pipeline đa thành phần, kiểm tra từng tầng độc lập luôn tiết kiệm thời gian hơn debug cả hệ thống cùng lúc.
Kết nối thiết bị ngoại vi cho voice + vision loop
Phần I/O trên Linux thường không khó, nhưng rất dễ gây khó chịu nếu nhảy thẳng vào chạy script mà chưa xác định đúng device.
Xác định microphone qua ALSA
arecord -l
Kết quả sẽ cho bạn biết card và device ID để dùng cho biến môi trường MIC_DEVICE.
Xác định speaker qua PulseAudio sink
pactl list short sinks
Bạn cần lấy đúng sink name cho SPK_DEVICE.
Xác định webcam qua V4L2
v4l2-ctl --list-devices
Nếu có nhiều camera, hãy xác định đúng index để gán vào WEBCAM.
Kiểm thử ghi âm và phát âm thanh trước khi vào runtime chính
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
Đây là bước rất nên làm, vì nếu bỏ qua, bạn sẽ khó phân biệt lỗi nằm ở:
- micro,
- loa,
- STT,
- TTS,
- hay cấu hình hệ điều hành.
Chạy demo Gemma 4 VLA trên Jetson
Sau khi backend LLM ổn và I/O ổn, phần còn lại là nối các mảnh lại với nhau.
Lấy mã nguồn demo
# Option 1: clone the whole repo
git clone https://github.com/asierarranz/Google_Gemma.git
cd Google_Gemma/Gemma4
# Option 2: just download the script
wget https://raw.githubusercontent.com/asierarranz/Google_Gemma/main/Gemma4/Gemma4_vla.py
Thiết lập biến môi trường runtime
Các biến quan trọng:
-
LLAMA_URL: endpoint củallama-server -
MIC_DEVICE: thiết bị micro -
SPK_DEVICE: thiết bị loa -
WEBCAM: chỉ số camera -
VOICE: voice của Kokoro
Chạy chế độ voice-interactive
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
Ở chế độ này, hệ thống sẽ:
- nghe người dùng,
- chuyển thành text,
- hỏi Gemma 4,
- gọi webcam nếu cần,
- và đọc lại câu trả lời bằng TTS.
Chạy text-only để debug nhanh
python3 Gemma4_vla.py --text
Chế độ này hữu ích khi bạn muốn tách riêng các vấn đề:
- backend LLM có phản hồi đúng không?
- tool calling có hoạt động không?
- prompt và logic hội thoại có ổn không?
Nó giúp loại bỏ biến số từ micro và loa khi debug.
Tùy chỉnh voice của Kokoro
export VOICE="am_puck"
python3 Gemma4_vla.py
Hoặc:
export VOICE="af_jessica"
python3 Gemma4_vla.py
Khả năng đổi voice không phải trọng tâm về AI, nhưng lại ảnh hưởng đáng kể đến trải nghiệm sử dụng thực tế.
Phân tích các tham số quan trọng trong lệnh llama-server
Trên desktop mạnh, người ta thường tăng cấu hình rồi “để model tự bơi”. Trên Jetson 8GB, cách đó gần như chắc chắn thất bại. Ở đây, từng tham số đều có lý do tồn tại.
-ngl 99 và --flash-attn on
-
-ngl 99- cố gắng đẩy càng nhiều layer càng tốt lên GPU;
- rất quan trọng để đạt hiệu năng chấp nhận được trên Orin.
-
--flash-attn on- giúp attention hiệu quả hơn;
- giảm chi phí tính toán và cải thiện độ mượt.
Nếu bỏ hai flag này, hệ thống vẫn có thể chạy, nhưng hiệu năng thường sẽ rơi xuống mức khó dùng cho tương tác thời gian thực.
Token budget cho hình ảnh và ảnh hưởng đến chi phí suy luận
--image-min-tokens 70 --image-max-tokens 70
Việc cố định token budget cho ảnh mang lại lợi ích:
- kiểm soát RAM tốt hơn,
- tránh chi phí vision tăng thất thường,
- giúp latency ổn định hơn giữa các lượt gọi.
Trên edge device, predictability thường quan trọng không kém peak performance.
Batch, ubatch, context window và cân bằng hiệu năng / bộ nhớ
Các flag đáng chú ý:
-c 2048--ubatch-size 512--batch-size 512
Đây là điểm cân bằng hợp lý cho demo:
-
context 2048
- đủ cho hội thoại ngắn và tool calling;
- không quá tham RAM.
-
batch / ubatch 512
- giúp throughput tốt hơn trong giới hạn máy;
- nhưng vẫn đủ an toàn cho Jetson 8GB nếu hệ thống sạch RAM.
Nếu nâng context quá cao hoặc dùng batch tham lam hơn, bạn có thể phải đánh đổi bằng:
- latency cao hơn,
- OOM,
- hoặc swap thrashing.
Lỗi thường gặp và cách khắc phục
Bản chất của một demo edge multimodal là: chạy được đã khó, chạy ổn còn khó hơn. Dưới đây là các vấn đề dễ gặp nhất.
1) OOM khi load model hoặc projector
Triệu chứng:
-
llama-serverthoát ngay khi nạp model - máy chậm hẳn rồi treo
- swap tăng mạnh nhưng không vào được runtime
Cách xử lý:
- dọn RAM trước khi chạy;
- tắt Docker, browser, IDE;
- bật swap 8GB;
- chuyển từ Q4_K_M xuống Q3_K_M;
- giữ đúng batch/context như cấu hình mẫu.
2) Không có âm thanh hoặc sai sink
Triệu chứng:
- script chạy nhưng không phát tiếng
- TTS sinh file xong nhưng loa im lặng
Cách xử lý:
pactl list short sinks
- kiểm tra đúng
SPK_DEVICE; - thử
paplayvới file test trước khi chạy script.
3) Mic thu im lặng
Triệu chứng:
- bấm nói nhưng STT không nhận được nội dung
- file thu gần như trống
Cách xử lý:
arecord -l
- kiểm tra lại
MIC_DEVICE; - thử ghi âm thủ công bằng
arecord; - xác minh micro webcam hoặc USB mic đã được hệ thống nhận đúng.
4) Lần chạy đầu tiên chậm bất thường
Lần khởi động đầu tiên có thể chậm hơn bình thường vì:
- model mới tải xong chưa warm-up;
- TTS assets cần chuẩn bị lần đầu;
- Python environment chưa cache đầy đủ.
Nếu lần đầu chậm nhưng các lần sau ổn hơn, đó thường là hành vi bình thường.
Tùy chọn thay thế: chạy nhanh bằng Docker
Không phải ai cũng muốn build native ngay từ đầu. Nếu chỉ cần thử Gemma 4 nhanh, Docker là lối vào dễ hơn.
Khi nào nên dùng Docker image dựng sẵn?
Docker phù hợp nếu bạn muốn:
- xác minh Gemma 4 chạy được trên Jetson,
- thử nhanh text inference,
- không cần webcam hay multimodal path.
Quickstart:
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
Vì sao Docker không phù hợp cho VLA đầy đủ?
Giới hạn quan trọng của đường Docker trong bài này là:
- phù hợp cho text-only;
- không phải lựa chọn tốt cho vision + mmproj + tool calling đầy đủ.
Nói cách khác:
- muốn thử Gemma 4 nhanh → Docker ổn;
- muốn chạy VLA thực sự → native
llama.cpplà con đường nên đi.
So sánh native multimodal với Docker text-only
Native build
- Ưu điểm:
- hỗ trợ đầy đủ multimodal
- dùng được
mmproj - hỗ trợ tool calling qua
--jinja - phù hợp với demo VLA hoàn chỉnh
- Nhược điểm:
- setup lâu hơn
- cần quản lý dependency và bộ nhớ kỹ hơn
Docker text-only
- Ưu điểm:
- khởi chạy nhanh
- ít công đoạn build
- phù hợp để smoke test
- Nhược điểm:
- không phải con đường lý tưởng cho full VLA
- kém linh hoạt hơn khi cần tích hợp vision thực sự
Ý nghĩa kỹ thuật của việc chạy multimodal agent trên edge 8GB
Điều thú vị nhất ở demo này không nằm ở chỗ “Gemma 4 chạy được trên Jetson”. Điều đáng nói hơn là:
- một multimodal agent tối giản có thể chạy cục bộ trên edge 8GB,
- với đủ các thành phần:
- STT,
- LLM/VLM,
- tool calling,
- webcam,
- TTS.
Nếu nhìn ở góc độ ứng dụng thực tế, kiến trúc này mở ra nhiều hướng triển khai:
- voice assistant nội bộ không phụ thuộc cloud,
- thiết bị giám sát riêng tư tại chỗ,
- trợ lý công nghiệp cho kiosk hoặc robot nhỏ,
- agent đa phương thức trong môi trường mạng hạn chế.
Quan trọng hơn, nó cho thấy một xu hướng ngày càng thực tế: local inference không còn chỉ là text chat. Ngay cả trên phần cứng khiêm tốn, ta đã có thể ghép thành hệ thống biết nghe, biết nhìn và biết quyết định khi nào cần nhìn.
Hướng mở rộng tiếp theo
Từ nền tảng này, có thể mở rộng khá tự nhiên sang:
-
nhiều tool hơn
- OCR
- object detection
- đọc cảm biến
- truy vấn hệ thống
-
loop tự động
- không cần nhấn phím SPACE
- wake-word hoặc VAD
-
camera policies
- chỉ chụp ảnh khi người dùng cho phép
- log lại khi nào tool vision được gọi
- thêm lớp kiểm soát quyền riêng tư
-
hành động vật lý
- GPIO
- điều khiển robot
- trigger thiết bị ngoại vi
Nếu chỉ xem đây là một demo “chat với webcam”, bạn sẽ bỏ lỡ giá trị thật của nó. Thực chất, đây là một ví dụ rõ ràng về cách xây dựng agent multimodal local-first trên phần cứng edge nhỏ gọn, nơi mà từng MB RAM và từng tham số runtime đều có ý nghĩa.
FAQ nhanh
Gemma 4 có chạy multimodal thật trên Jetson Orin Nano 8GB không?
Có, nhưng cần tối ưu đúng cách: dùng GGUF quantized model, thêm mmproj, bật --jinja, dọn RAM và thường nên có swap.
Nên chọn quantization nào?
- Ưu tiên:
Q4_K_M - Fallback khi thiếu RAM:
Q3_K_M - Docker text-only:
Q4_K_S
Có bắt buộc dùng Docker không?
Không. Với bài toán VLA đầy đủ, native llama.cpp là lựa chọn phù hợp hơn Docker.
Có cần gọi vision ở mọi lượt không?
Không. Đây chính là điểm mạnh của demo: model tự quyết định khi nào cần dùng webcam thông qua tool calling.
Phụ lục lệnh triển khai nhanh
Lấy mã nguồn demo
# Option 1: clone the whole repo
git clone https://github.com/asierarranz/Google_Gemma.git
cd Google_Gemma/Gemma4
# Option 2: just download the script
wget https://raw.githubusercontent.com/asierarranz/Google_Gemma/main/Gemma4/Gemma4_vla.py
Cài system packages
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
Tạo Python environment
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
Tạo swap
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
Giải phóng RAM
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
Fallback quant nhẹ hơn
gemma-4-E2B-it-Q3_K_M.gguf # instead of Q4_K_M
Build 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
Tải model và vision projector
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
Khởi động llama-server
~/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
Verify API endpoint
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
Liệt kê mic
arecord -l
Liệt kê speaker sinks
pactl list short sinks
Liệt kê webcam
v4l2-ctl --list-devices
Test audio I/O
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
Chạy demo VLA
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
Chạy text-only mode
python3 Gemma4_vla.py --text
Đổi voice
export VOICE="am_puck"
python3 Gemma4_vla.py
Tool definition
{
"name": "look_and_answer",
"description": "Take a photo with the webcam and analyze what is visible."
}
Docker text-only quickstart
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
Top comments (0)