Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Assists the user to calibrate, merge, and statically quantize litert LLM models (such as Gemma 3) in standard open-source (OSS) environments. Use when the user wants to run LLM calibration, merge task JSON results, align KV cache parameters across models, protect sensitive layers in Float32, or run quantized inference testing. Don't use for JAX/PyTorch custom quantization configurations or non-litert models.
.claude/skills/google-ai-edge-litert-quantization-calib/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 114% | 0% |
A skill to guide the calibration, alignment, precision protection, and static range quantization of LiteRT LLMs (such as Gemma 3 1B) for high-performance NPU deployments.
datasets.
tasks.
configurations).
noise in Float32.
main and auxiliary models.
quantized LiteRT models.
models).
or KV caches.
Every LLM NPU quantization task has highly sensitive numerical paths. You must strictly adhere to these verified gotchas to prevent quality degradation or loop crashes:
2) will completelycorrupt the model's attention states and positional encodings at step 0. This causes the model to generate garbage loop outputs (e.g. does France does France infinitely) during both calibration and inference.
prepend_bos=True is active during alltokenization operations. If using the open-source SentencePiece or Transformers tokenizers, verify that the BOS token ID (2) is explicitly prepended to the start of the token IDs list.
allow_float_operations=True)additions, or skip scale multipliers down to Int8/Int16 introduces severe quantization noise that ruins text generation quality.
or norm nodes): Skip from quantization to prevent numerical accuracy loss.
immediately following attention or MLP projection blocks): Keep in Float32.
multiplication nodes matching the skip connection scaling factors): Keep in Float32.
align_kv_cache=True)(prefill/decode subgraphs) and auxiliary model must use identical scaling factors (scale and zero-point) so the hardware NPU can reuse slices dynamically without expensive runtime rescalings.
align_kv_cache_params() to search and align all Kand V cache layers across the model suite before calling the quantizer.
embedder.tflite in Float32 (Never Quantize)its weights leads to massive accuracy degradation. Since the embedder only executes once at step 0 (prefill), it has zero speed impact.
embedder.tflite. Copy the original Float32version directly into the final quantized deployment folder.
use_profiler_based_calibration=True)--use_profiler_based_calibration=True to run the calibration interpreter in profiler mode. This extracts precise tensor bounds directly from the interpreter's internal profiling metrics. This mode requires --enable_min_max_calibration_update=True to correctly update the min/max calibration parameters.--skip_mlir_passes=True to bypass failing MLIR optimizations for sensitive custom model architectures.--calibration_range_scale=1.15 (or a similar factor) to slightly scale up the calibration bounds, providing headroom for outliers and reducing clipping distortion.Generates the calibration range JSONs under a task-specific sub-directory:
bashpython3 -m litert_torch.generative.export_hf.experimental.calib.calibrate \ --model_path={model_path} \ --embedder_model_path={embedder_path} \ --auxiliary_model_path={aux_path} \ --spm_path={tokenizer_spm_path} \ --calibration_eval_task_names="{task_name}" \ --calibration_dataset_dir={dataset_dir} \ --calibration_dataset_format=json \ --calibration_result_save_dir={output_save_dir}/{task_name} \ --max_calibration_decode_steps=128 \ --use_profiler_based_calibration=True \ --enable_min_max_calibration_update=True
Discovers and merges QSV files across task sub-directories into a single aligned calibration file:
bashpython3 -m litert_torch.generative.export_hf.experimental.calib.merge_calibration_results \ --input_dir={calibration_dir} \ --output_dir={merged_output_dir}
Note: The merger expects a directory structure where task files are grouped inside sub-folders (e.g. input_dir/task_name/model.tflite.json). Flat folders will result in no tasks discovered.
Statically quantizes both the main model and the auxiliary model with KV Cache Alignment and Float Protection active:
bashpython3 -m litert_torch.generative.export_hf.experimental.calib.quantize \ --model_path={model_path} \ --calibration_path={merged_dir}/model.tflite.json \ --output_path={quantized_dir}/model.tflite \ --aux_model_path={aux_path} \ --aux_calibration_path={merged_dir}/aux.tflite.json \ --aux_output_path={quantized_dir}/aux.tflite \ --a16w8={true_or_false} \ --align_kv_cache=True \ --allow_float_operations=True \ --skip_mlir_passes=True \ --calibration_range_scale=1.15
Executes text generation using the quantized model suite:
bashpython3 -m litert_torch.generative.export_hf.experimental.calib.sampling_executor_main \ --model_path={quantized_dir}/model.tflite \ --embedder_model_path={embedder_path} \ --auxiliary_model_path={quantized_dir}/aux.tflite \ --spm_path={tokenizer_spm_path} \ --prompt="{prompt_text}" \ --enable_formatting=False \ --max_decode_steps=16 \ --stop_token={stop_token_id} \ --stream_output=True
Note: For Gemma 3, set --stop_token=106 to ensure the executor cleanly halts immediately when the model generates its end-of-turn sequence.
For the easiest, most robust end-to-end execution, you can use the interactive bash script inside the repository: bash cd litert_torch/generative/export_hf/experimental/calib/ ./run_quantize_and_inference.sh This script provides interactive path configuration, parallel calibration task management, automatic task grouping, merging, and A16W8/A8W8 recipe quantization!
Other measured skills in the registry, with their headline benchmark lift.