Local Gemma 4 workstation lab with:
vLLM bridge for nvidia/Gemma-4-31B-IT-NVFP4Useful docs:
Use the bootstrap script below if you want the repo to install its Python deps, web deps, llama.cpp, the WSL vLLM env for NVFP4, the Piper voice, then prefetch every Gemma checkpoint used by the lab:
.\install_and_run_gemma4_lab.ps1
What it does:
.venvrequirements-lab.txtnpm ci and npm run build in [web/package.json](C:/Users/Anis AYARI/Desktop/projects/gemma4-test/web/package.json)llama.cpp binaries if tools/llama.cpp/bin is missing~/vllm-gemma4 inside WSL Ubuntu for nvidia/Gemma-4-31B-IT-NVFP4NVFP4 checkpoint, and the default Piper voiceImportant notes:
NVFP4 setup expects a WSL distro named Ubuntu.\.hf-cache, so the NVIDIA path does not redownload weights once they are prefetchedOnce the environment is already installed, the fast path is:
.\run_gemma4_lab.ps1
That script rebuilds the frontend, stops any previous process already bound to port 8000, and starts the FastAPI app.
If you want to prepare everything without immediately starting the server:
.\install_and_run_gemma4_lab.ps1 -InstallOnly
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipWSLNVFP4
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipModelDownloads
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipGGUF -SkipNVFP4
These are the main switches:
-SkipWSLNVFP4: skip the WSL vLLM environment for the NVIDIA model-SkipModelDownloads: install dependencies only, without prefetching checkpoints-SkipBF16: skip the official Google BF16 checkpoints-SkipGGUF: skip the llama.cpp quantized checkpoints-SkipNVFP4: skip the NVIDIA nvidia/Gemma-4-31B-IT-NVFP4 checkpoint-SkipTTS: skip the local Piper voice assetsIf you already have the env and just want to fill the shared cache manually:
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py
Examples:
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py --skip-nvfp4
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py --skip-gguf --skip-tts
NVIDIA GeForce RTX 5090 32 GB581.42AMD Ryzen 9 9950X3D2026-04-04Three benchmark paths were measured:
BF16 with the local Transformers runtime used by the app backendGGUF models with llama.cpp CUDANVFP4 / ModelOpt FP4 with vLLM on WSL UbuntuImportant note:
BF16 / SFP8 / Q4_0SFP8 slot is now routed to a practical local Q8_0 GGUF runtime through llama.cppQ8_0, not the exact Google SFP8 tensor formatQ4_0This is what the current app actually does when you click Load model:
| UI quantization | Actual local runtime | Checkpoint family |
|---|---|---|
BF16 | Transformers | official Hugging Face Google checkpoints |
SFP8 | llama.cpp | Q8_0 GGUF fallback used as the local 8-bit path |
Q4_0 | llama.cpp | Q4_0 GGUF |
NVFP4 | vLLM on WSL Ubuntu | nvidia/Gemma-4-31B-IT-NVFP4 |
Load status validated in the current lab build:
Gemma 4 E2B / SFP8 loads and answers through llama.cppGemma 4 E4B / SFP8 loads through llama.cppGemma 4 26B A4B / SFP8 loads through llama.cppGemma 4 31B / SFP8 loads and answers through llama.cppGemma 4 31B IT NVFP4 / NVFP4 loads and answers through WSL vLLMNote:
benchmark/resultsSFP8 -> Q8_0 fixesThis chart uses:
X = total model size in billions of parametersY = measured generation tokens per second16-bit larger than 8-bit, and 8-bit larger than 4-bitKO models shown on the right when they did not run cleanly on this workstationxychart-beta
title "Gemma 4 BF16 Generation Throughput on RTX 5090"
x-axis ["E2B BF16", "E4B BF16"]
y-axis "tokens / second" 0 --> 20
bar [15.96, 13.23]
xychart-beta
title "Gemma 4 Quantized Generation Throughput on RTX 5090"
x-axis ["E2B Q8", "E2B Q4", "E4B Q8", "E4B Q4", "26B Q8", "26B Q4", "31B Q4", "31B NVFP4"]
y-axis "tokens / second" 0 --> 300
bar [243.41, 285.29, 154.83, 191.27, 166.75, 184.50, 66.12, 7.80]
The API load test exercises the real local HTTP server rather than raw model runners. It measures:
Latest artifacts:
Current snapshot:
| Model | Load | Short request | Medium request | Long request |
|---|---|---|---|---|
E2B / SFP8 | 0.03s | 0.35s | 0.82s | 1.22s |
E2B / Q4_0 | 29.09s | 0.46s | 0.84s | 1.21s |
E4B / SFP8 | 32.19s | 0.56s | 1.06s | 1.57s |
E4B / Q4_0 | 31.03s | 0.45s | 0.86s | 1.30s |
26B A4B / SFP8 | 35.29s | 0.83s | 1.96s | 3.15s |
26B A4B / Q4_0 | 71.70s | 0.49s | 0.90s | 1.41s |
31B / Q4_0 | 54.69s | 0.86s | 2.48s | 3.73s |
31B / SFP8 | 45.91s | 8.06s | 23.39s | 34.42s |
Quick read:
E2B / SFP826B A4B / Q4_031B / SFP831B IT NVFP4 / NVFP4 did not load on this workstation in the API load testRuntime:
Transformers| Model | Status | Mean gen tok/s | Best gen tok/s | Load time | VRAM after load |
|---|---|---|---|---|---|
| Gemma 4 E2B | ok | 15.96 | 16.20 | 10.69 s | 9.67 GiB |
| Gemma 4 E4B | ok | 13.23 | 13.26 | 11.10 s | 14.90 GiB |
| Gemma 4 26B A4B | failed | - | - | - | - |
| Gemma 4 31B | failed | - | - | - | - |
BF16 failure notes:
Gemma 4 26B A4B: Windows paging file / commit limit failure during loadGemma 4 31B: Windows paging file / commit limit failure during loadRuntime:
llama.cpp CUDA256 prompt tokens128 generated tokens2| Model | Quant | Source | Prompt tok/s | Gen tok/s | Status |
|---|---|---|---|---|---|
| Gemma 4 E2B | Q8_0 | official | 16545.45 | 243.41 | ok |
| Gemma 4 E2B | Q4_0 | community | 13077.21 | 285.29 | ok |
| Gemma 4 E4B | Q8_0 | official | 10537.28 | 154.83 | ok |
| Gemma 4 E4B | Q4_0 | community | 9387.39 | 191.27 | ok |
| Gemma 4 26B A4B | Q8_0 | official | 5795.03 | 166.75 | ok |
| Gemma 4 26B A4B | Q4_0 | community | 5267.01 | 184.50 | ok |
| Gemma 4 31B | Q8_0 | official | - | - | failed |
| Gemma 4 31B | Q4_0 | community | 3530.86 | 66.12 | ok |
Quantized failure notes:
Gemma 4 31B Q8_0: CUDA load failure on this RTX 5090 setup with the tested llama.cpp buildRuntime:
vLLM 0.19.0 on WSL Ubuntunvidia/Gemma-4-31B-IT-NVFP4VLLM_NVFP4_GEMM_BACKEND=cutlassmax_model_len=256, gpu_memory_utilization=0.94, max_tokens=64, enforce_eager=True, cpu_offload_gb=0.0| Model | Quant | Runtime | Status | Gen tok/s | Load time | Notes |
|---|---|---|---|---|---|---|
| Gemma 4 31B IT NVFP4 | NVFP4 | WSL vLLM | ok | 7.80 | 322.00 s | validated on RTX 5090 single-GPU setup |
NVFP4 notes:
vLLM, NVIDIA Blackwell, and preferred OS LinuxWSL bridge in the labmax_model_len=256 so text and image turns fit cleanly on this RTX 5090 setup256 context because that was the most stable high-pressure config for measuring decode speedGemma 4 E2B Q4_0 at 285.29 tok/sGemma 4 E4B Q4_0 at 191.27 tok/sGemma 4 31B Q4_0 at 66.12 tok/sGemma 4 26B A4B Q4_0 at 184.50 tok/sGemma 4 31B IT NVFP4 now runs in the lab through WSL vLLM at 7.80 tok/s31B Q4_0 remains much faster than 31B NVFP4; the NVIDIA checkpoint is more about compatibility with the official ModelOpt/vLLM stack than raw local throughput herebenchmark/results/gemma4-5090-summary-20260404.mdbenchmark/results/gemma4-gguf-benchmark-20260404-202529.mdbenchmark/results/gemma4-nvfp4-vllm-summary-latest.mdbenchmark/results/gemma4-nvfp4-vllm-summary-20260405.mdbenchmark/results/gemma4-5090-benchmark-20260404-194128.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194004.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194021.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194036.jsonbenchmark/results/gemma4-gguf-benchmark-20260404-202529.jsonbenchmark/results/gemma4-nvfp4-vllm-benchmark-latest.jsonBF16:
.\.venv\Scripts\python.exe .\benchmark\benchmark_gemma4.py --models e2b e4b 26b-a4b 31b --max-new-tokens 128 --warmup-tokens 32 --runs 2
GGUF:
.\.venv\Scripts\python.exe .\benchmark\benchmark_gemma4_gguf.py
NVFP4:
.\.venv\Scripts\python.exe .\benchmark\benchmark_nvfp4_vllm_guarded.py --max-model-len 256 --gpu-memory-utilization 0.94 --max-tokens 64
15 commits
Python
42.1%
HTML
31.0%
JavaScript
19.8%
CSS
6.0%
PowerShell
1.1%
Local Gemma 4 workstation lab with:
vLLM bridge for nvidia/Gemma-4-31B-IT-NVFP4Useful docs:
Use the bootstrap script below if you want the repo to install its Python deps, web deps, llama.cpp, the WSL vLLM env for NVFP4, the Piper voice, then prefetch every Gemma checkpoint used by the lab:
.\install_and_run_gemma4_lab.ps1
What it does:
.venvrequirements-lab.txtnpm ci and npm run build in [web/package.json](C:/Users/Anis AYARI/Desktop/projects/gemma4-test/web/package.json)llama.cpp binaries if tools/llama.cpp/bin is missing~/vllm-gemma4 inside WSL Ubuntu for nvidia/Gemma-4-31B-IT-NVFP4NVFP4 checkpoint, and the default Piper voiceImportant notes:
NVFP4 setup expects a WSL distro named Ubuntu.\.hf-cache, so the NVIDIA path does not redownload weights once they are prefetchedOnce the environment is already installed, the fast path is:
.\run_gemma4_lab.ps1
That script rebuilds the frontend, stops any previous process already bound to port 8000, and starts the FastAPI app.
If you want to prepare everything without immediately starting the server:
.\install_and_run_gemma4_lab.ps1 -InstallOnly
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipWSLNVFP4
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipModelDownloads
.\install_and_run_gemma4_lab.ps1 -InstallOnly -SkipGGUF -SkipNVFP4
These are the main switches:
-SkipWSLNVFP4: skip the WSL vLLM environment for the NVIDIA model-SkipModelDownloads: install dependencies only, without prefetching checkpoints-SkipBF16: skip the official Google BF16 checkpoints-SkipGGUF: skip the llama.cpp quantized checkpoints-SkipNVFP4: skip the NVIDIA nvidia/Gemma-4-31B-IT-NVFP4 checkpoint-SkipTTS: skip the local Piper voice assetsIf you already have the env and just want to fill the shared cache manually:
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py
Examples:
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py --skip-nvfp4
.\.venv\Scripts\python.exe .\scripts\prefetch_gemma4_assets.py --skip-gguf --skip-tts
NVIDIA GeForce RTX 5090 32 GB581.42AMD Ryzen 9 9950X3D2026-04-04Three benchmark paths were measured:
BF16 with the local Transformers runtime used by the app backendGGUF models with llama.cpp CUDANVFP4 / ModelOpt FP4 with vLLM on WSL UbuntuImportant note:
BF16 / SFP8 / Q4_0SFP8 slot is now routed to a practical local Q8_0 GGUF runtime through llama.cppQ8_0, not the exact Google SFP8 tensor formatQ4_0This is what the current app actually does when you click Load model:
| UI quantization | Actual local runtime | Checkpoint family |
|---|---|---|
BF16 | Transformers | official Hugging Face Google checkpoints |
SFP8 | llama.cpp | Q8_0 GGUF fallback used as the local 8-bit path |
Q4_0 | llama.cpp | Q4_0 GGUF |
NVFP4 | vLLM on WSL Ubuntu | nvidia/Gemma-4-31B-IT-NVFP4 |
Load status validated in the current lab build:
Gemma 4 E2B / SFP8 loads and answers through llama.cppGemma 4 E4B / SFP8 loads through llama.cppGemma 4 26B A4B / SFP8 loads through llama.cppGemma 4 31B / SFP8 loads and answers through llama.cppGemma 4 31B IT NVFP4 / NVFP4 loads and answers through WSL vLLMNote:
benchmark/resultsSFP8 -> Q8_0 fixesThis chart uses:
X = total model size in billions of parametersY = measured generation tokens per second16-bit larger than 8-bit, and 8-bit larger than 4-bitKO models shown on the right when they did not run cleanly on this workstationxychart-beta
title "Gemma 4 BF16 Generation Throughput on RTX 5090"
x-axis ["E2B BF16", "E4B BF16"]
y-axis "tokens / second" 0 --> 20
bar [15.96, 13.23]
xychart-beta
title "Gemma 4 Quantized Generation Throughput on RTX 5090"
x-axis ["E2B Q8", "E2B Q4", "E4B Q8", "E4B Q4", "26B Q8", "26B Q4", "31B Q4", "31B NVFP4"]
y-axis "tokens / second" 0 --> 300
bar [243.41, 285.29, 154.83, 191.27, 166.75, 184.50, 66.12, 7.80]
The API load test exercises the real local HTTP server rather than raw model runners. It measures:
Latest artifacts:
Current snapshot:
| Model | Load | Short request | Medium request | Long request |
|---|---|---|---|---|
E2B / SFP8 | 0.03s | 0.35s | 0.82s | 1.22s |
E2B / Q4_0 | 29.09s | 0.46s | 0.84s | 1.21s |
E4B / SFP8 | 32.19s | 0.56s | 1.06s | 1.57s |
E4B / Q4_0 | 31.03s | 0.45s | 0.86s | 1.30s |
26B A4B / SFP8 | 35.29s | 0.83s | 1.96s | 3.15s |
26B A4B / Q4_0 | 71.70s | 0.49s | 0.90s | 1.41s |
31B / Q4_0 | 54.69s | 0.86s | 2.48s | 3.73s |
31B / SFP8 | 45.91s | 8.06s | 23.39s | 34.42s |
Quick read:
E2B / SFP826B A4B / Q4_031B / SFP831B IT NVFP4 / NVFP4 did not load on this workstation in the API load testRuntime:
Transformers| Model | Status | Mean gen tok/s | Best gen tok/s | Load time | VRAM after load |
|---|---|---|---|---|---|
| Gemma 4 E2B | ok | 15.96 | 16.20 | 10.69 s | 9.67 GiB |
| Gemma 4 E4B | ok | 13.23 | 13.26 | 11.10 s | 14.90 GiB |
| Gemma 4 26B A4B | failed | - | - | - | - |
| Gemma 4 31B | failed | - | - | - | - |
BF16 failure notes:
Gemma 4 26B A4B: Windows paging file / commit limit failure during loadGemma 4 31B: Windows paging file / commit limit failure during loadRuntime:
llama.cpp CUDA256 prompt tokens128 generated tokens2| Model | Quant | Source | Prompt tok/s | Gen tok/s | Status |
|---|---|---|---|---|---|
| Gemma 4 E2B | Q8_0 | official | 16545.45 | 243.41 | ok |
| Gemma 4 E2B | Q4_0 | community | 13077.21 | 285.29 | ok |
| Gemma 4 E4B | Q8_0 | official | 10537.28 | 154.83 | ok |
| Gemma 4 E4B | Q4_0 | community | 9387.39 | 191.27 | ok |
| Gemma 4 26B A4B | Q8_0 | official | 5795.03 | 166.75 | ok |
| Gemma 4 26B A4B | Q4_0 | community | 5267.01 | 184.50 | ok |
| Gemma 4 31B | Q8_0 | official | - | - | failed |
| Gemma 4 31B | Q4_0 | community | 3530.86 | 66.12 | ok |
Quantized failure notes:
Gemma 4 31B Q8_0: CUDA load failure on this RTX 5090 setup with the tested llama.cpp buildRuntime:
vLLM 0.19.0 on WSL Ubuntunvidia/Gemma-4-31B-IT-NVFP4VLLM_NVFP4_GEMM_BACKEND=cutlassmax_model_len=256, gpu_memory_utilization=0.94, max_tokens=64, enforce_eager=True, cpu_offload_gb=0.0| Model | Quant | Runtime | Status | Gen tok/s | Load time | Notes |
|---|---|---|---|---|---|---|
| Gemma 4 31B IT NVFP4 | NVFP4 | WSL vLLM | ok | 7.80 | 322.00 s | validated on RTX 5090 single-GPU setup |
NVFP4 notes:
vLLM, NVIDIA Blackwell, and preferred OS LinuxWSL bridge in the labmax_model_len=256 so text and image turns fit cleanly on this RTX 5090 setup256 context because that was the most stable high-pressure config for measuring decode speedGemma 4 E2B Q4_0 at 285.29 tok/sGemma 4 E4B Q4_0 at 191.27 tok/sGemma 4 31B Q4_0 at 66.12 tok/sGemma 4 26B A4B Q4_0 at 184.50 tok/sGemma 4 31B IT NVFP4 now runs in the lab through WSL vLLM at 7.80 tok/s31B Q4_0 remains much faster than 31B NVFP4; the NVIDIA checkpoint is more about compatibility with the official ModelOpt/vLLM stack than raw local throughput herebenchmark/results/gemma4-5090-summary-20260404.mdbenchmark/results/gemma4-gguf-benchmark-20260404-202529.mdbenchmark/results/gemma4-nvfp4-vllm-summary-latest.mdbenchmark/results/gemma4-nvfp4-vllm-summary-20260405.mdbenchmark/results/gemma4-5090-benchmark-20260404-194128.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194004.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194021.jsonbenchmark/results/gemma4-5090-benchmark-20260404-194036.jsonbenchmark/results/gemma4-gguf-benchmark-20260404-202529.jsonbenchmark/results/gemma4-nvfp4-vllm-benchmark-latest.jsonBF16:
.\.venv\Scripts\python.exe .\benchmark\benchmark_gemma4.py --models e2b e4b 26b-a4b 31b --max-new-tokens 128 --warmup-tokens 32 --runs 2
GGUF:
.\.venv\Scripts\python.exe .\benchmark\benchmark_gemma4_gguf.py
NVFP4:
.\.venv\Scripts\python.exe .\benchmark\benchmark_nvfp4_vllm_guarded.py --max-model-len 256 --gpu-memory-utilization 0.94 --max-tokens 64
15 commits
Python
42.1%
HTML
31.0%
JavaScript
19.8%
CSS
6.0%
PowerShell
1.1%