[BUG] Qwen3-TTS CP-FP8 calibration failed, it mixes text and codec embedding domains
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- python
- Domain
- machine-learning, tooling
Research direction
Start with tensorrt_edgellm/quantization/qwen3_cp_loader.py and quantize.py, then reproduce the documented CP-only FP8 command for the Qwen3-TTS checkpoint. Trace the text, codec, and residual embedding inputs and the generic model-loading path. Done means the official checkpoint loads and calibration produces the documented precision split without mixing token domains.
Written by the indexing model from the issue text.
Description
Describe the bug
v0.10.0 documents FP8 quantization support for the Qwen3-TTS CodePredictor through:
tensorrt-edgellm-quantize llm ... --cp_quantization fp8
However, the Qwen3-TTS CodePredictor calibration path does not preserve the model's separate text-token and codec-token embedding domains.
This is a blocker for the documented Qwen3-TTS CodePredictor FP8 workflow. The supported precision contract is otherwise appropriate for this model:
- Talker: FP16
- CodePredictor: FP8 only
- Code2Wav: FP16
- KV cache: FP16
The issue is in tensorrt_edgellm/quantization/qwen3_cp_loader.py.
For Qwen3-TTS, _talker_inputs_from_text() sends tokenizer text IDs to talker.get_input_embeddings():
def _talker_inputs_from_text(model, input_ids):
talker = model.talker
talker_embed = talker.get_input_embeddings()
return talker_embed(input_ids).to(talker.dtype)
The same talker_embed is then reused for the initial CodePredictor input:
talker_vocab = talker_cfg.text_config.vocab_size
# ...
random_token = torch.randint(0, talker_vocab, (bsz, 1), device=device)
last_token_embed = talker_embed(random_token).to(talker.dtype)
For the official Qwen3-TTS model, these are distinct domains:
- Text tokens must use the Talker text embedding followed by
text_projection. - Talker codec tokens use the Talker codec embedding.
- CodePredictor residual tokens use the CodePredictor per-codebook codec embeddings.
The exporter already reflects this separation by emitting both text_embedding.safetensors / text_projection.safetensors and codec embedding sidecars. The calibration path does not.
As a result, text-token IDs, or random IDs sampled from the text vocabulary, can be passed to a codec embedding table. This leads to CUDA embedding index-out-of-range failures. Mapping get_input_embeddings() to the text embedding is not a valid workaround either, because the later CP seed requires codec-embedding semantics.
There is also a loading issue in the documented generic quantization path. The official Qwen3-TTS checkpoint uses model_type: "qwen3_tts", while the generic quantizer loads via Transformers AutoModel factories and does not have a Qwen3-TTS-specific loader or qwen_tts registration path. With the stock Transformers package, model loading can fail before calibration with an unrecognized qwen3_tts configuration/model type.
This report concerns the calibration-interface mismatch after model loading. A valid fix likely needs a dedicated Qwen3-TTS loader and calibration adapter rather than changing the meaning of get_input_embeddings() globally.
Steps/Code to reproduce bug
- Start from TensorRT Edge-LLM
v0.10.0. - Install the tool dependencies and the official Qwen TTS package.
- Download the official Qwen3-TTS CustomVoice checkpoint.
- Run CP-only FP8 quantization as documented.
Installation method:
Built TensorRT Edge-LLM from source at tag v0.10.0 inside a Docker container.
git checkout v0.10.0
pip install ".[tools]"
pip install qwen-tts==0.1.1
Export command used:
export MODEL_DIR=/workspace/models/Qwen3-TTS-12Hz-0.6B-CustomVoice
export QUANTIZED_MODEL_DIR=/workspace/models/Qwen3-TTS-12Hz-0.6B-CustomVoice-CP-FP8
tensorrt-edgellm-quantize llm \
--model_dir "$MODEL_DIR" \
--output_dir "$QUANTIZED_MODEL_DIR" \
--cp_quantization fp8 \
--dtype fp16 \
--device cuda \
--num_samples 64
The same issue applies when using the official Hugging Face model ID instead of a local directory:
tensorrt-edgellm-quantize llm \
--model_dir Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice \
--output_dir /workspace/models/Qwen3-TTS-12Hz-0.6B-CustomVoice-CP-FP8 \
--cp_quantization fp8 \
--dtype fp16 \
--device cuda \
--num_samples 64
Observed failure modes:
- With stock Transformers AutoModel loading, the official checkpoint can fail to load because
model_type="qwen3_tts"is not registered by Transformers alone. - When the official
qwen-ttsmodel is loaded through a compatibility/registration path, calibration reaches the TTS CodePredictor loop and can fail with CUDA embedding index-out-of-range because text-vocabulary IDs are used with a codec embedding table.
Relevant source locations in v0.10.0:
tensorrt_edgellm/quantization/qwen3_cp_loader.py_talker_inputs_from_text()usestalker.get_input_embeddings()for tokenizer text IDs.random_tokenis sampled fromtalker_cfg.text_config.vocab_sizeand passed to that same embedding.
tensorrt_edgellm/quantization/quantize.py- The generic
_load_model()path uses AutoModel factories. - No Qwen3-TTS-specific loader is present, unlike the dedicated Qwen3-ASR loader.
- The generic
Expected behavior
The documented command below should successfully produce a CP-only FP8 quantized checkpoint for the official Qwen3-TTS checkpoint:
tensorrt-edgellm-quantize llm \
--model_dir Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice \
--output_dir ./qwen3-tts-cp-fp8 \
--cp_quantization fp8
The implementation should:
- Load the official Qwen3-TTS checkpoint through an explicit Qwen3-TTS loader/registration path.
- Keep Talker, Code2Wav, and KV cache in FP16.
- Quantize only
talker.code_predictor.*to FP8, while retainingdown_proj, CP LM heads, and KV-cache BMM in FP16 as documented. - Drive calibration with the model's real TTS input contract:
- text token IDs -> text embedding -> text projection -> Talker;
- codec token IDs -> codec embedding -> Talker/CodePredictor;
- residual CP tokens -> the corresponding CodePredictor codec embedding.
- Avoid using a single
get_input_embeddings()API for both text and codec token domains.
System information (x86 Host with GPU)
======================================================================
- Container used (if applicable): Yes.
- OS (e.g., Ubuntu 22.04, CentOS 7): Ubuntu 24.04.3 LTS
- CPU architecture: x86_64
- GPU name (e.g. H100, A100, RTX 4090): NVIDIA L4
- GPU memory size: 24.0 GB
- Number of GPUs: 2
- Library versions:
- Python: 3.12.3
- TensorRT Edge-LLM version or commit hash:
v0.10.0(71dd1bae032e70771265917ec74d3ff4cad07a10) - CUDA: 13.1
- PyTorch: 2.13.0+cu130
- Transformers: 5.14.1
- ModelOpt: 0.44.0
- ONNX: 1.19.0
- Any other details that may help:
- Model:
Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice - The same model was also reproduced from a local downloaded checkpoint directory.
qwen-tts==0.1.1is installed.- The TensorRT Edge-LLM
v0.10.0pyproject.tomlpinsnvidia-modelopt==0.45.0, while this environment currently has ModelOpt 0.44.0. The embedding-domain issue is visible in thev0.10.0calibration source independently of that version difference. - TTS FP16 export/build/inference works; this report is specifically about the documented CP-only FP8 quantization path.
- Model:
======================================================================
- Dominant language
- Python
- Stars
- 563
- Forks
- 135
- Avg merge
- 14h 13m
- Merged PRs (30d)
- 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from NVIDIA/TensorRT-Edge-LLM
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
NVIDIA/TensorRT-Edge-LLM#211 · 2 comments ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
NVIDIA/TensorRT-Edge-LLM#183 · 4 comments · 1 reaction ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
NVIDIA/TensorRT-Edge-LLM#165 · 2 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
NVIDIA/TensorRT-Edge-LLM#144 · 1 comment ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
NVIDIA/TensorRT-Edge-LLM#125 · 1 comment ·
All issues in NVIDIA/TensorRT-Edge-LLM
Similar issues
-
bug priority:low
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
CyberAgent/psd2svg#436 ·
-
area/install-update comp/cli comp/desktop P3 sweeper:risk-compatibility type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
NousResearch/hermes-agent#122386 · 1 comment ·
-
ai-generated
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
vllm-project/production-stack#1105 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100