unslothai/unsloth · error · ValueError
No bicodec_semantic tokens found in generated output
Error message
No bicodec_semantic tokens found in generated output
What it means
Raised during BiCodec (e.g. MeiGate/E2-style TTS) decode when the regex for <|bicodec_semantic_N|> tokens finds zero matches in the generated text. The LLM was supposed to emit semantic tokens as inline special-token text but produced none — the generation ended early, used the wrong template, or the tokenizer does not mark these ids as special so they never render in the text.
Source
Thrown at studio/backend/core/inference/audio_codecs.py:209
return _numpy_to_wav_bytes(waveform, 24000), 24000
def decode_bicodec(self, generated_text: str, device: str) -> Tuple[bytes, int]:
"""Decode BiCodec tokens (Spark-TTS) from generated text.
Extracts bicodec_semantic_N and bicodec_global_N tokens via regex.
Returns (wav_bytes, sample_rate).
"""
semantic_matches = re.findall(r"<\|bicodec_semantic_(\d+)\|>", generated_text)
global_matches = re.findall(r"<\|bicodec_global_(\d+)\|>", generated_text)
logger.info(
f"BiCodec decode: {len(global_matches)} global tokens, {len(semantic_matches)} semantic tokens"
)
if len(global_matches) < 10:
logger.info(f"BiCodec generated text (first 500 chars): {generated_text[:500]}")
if not semantic_matches:
raise ValueError("No bicodec_semantic tokens found in generated output")
semantic_ids = torch.tensor([int(t) for t in semantic_matches]).long().unsqueeze(0)
# Speaker encoder expects exactly 32 global tokens (token_num=32);
# pad with zeros or truncate.
GLOBAL_TOKEN_NUM = 32
if global_matches:
raw = [int(t) for t in global_matches]
else:
raw = []
if len(raw) < GLOBAL_TOKEN_NUM:
raw = raw + [0] * (GLOBAL_TOKEN_NUM - len(raw))
raw = raw[:GLOBAL_TOKEN_NUM]
global_ids = torch.tensor(raw).long().unsqueeze(0) # (1, 32)
self._bicodec_tokenizer.device = device
self._bicodec_tokenizer.model.to(device)
View on GitHub (pinned to 203007d190)
Solutions
- Inspect the logged 'BiCodec generated text (first 500 chars)' to see what the model actually produced — prose instead of tokens means a prompt/template problem
- Ensure the model's tokenizer_config registers the bicodec_semantic/bicodec_global tokens as special tokens
- Adjust sampling (temperature, min_p, repetition penalty) and retry — early-EOS is often stochastic
- Confirm the loaded checkpoint is the audio-capable variant and the generation prompt includes the required prefix
Defensive patterns
Strategy: fallback
Validate before calling
import re
def has_bicodec_output(text: str) -> bool:
return bool(re.search(r"<\|bicodec_semantic_\d+\|>", text)) Try / catch
try:
wav, sr = codec.decode_bicodec(generated_text, device)
except ValueError as e:
if "bicodec_semantic" in str(e):
log_first_500(generated_text) # inspect what the model emitted
regenerate() Prevention
- Confirm bicodec tokens are registered as special tokens in tokenizer_config
- Use the model card's exact TTS prompt structure
- Watch the logged token counts (global vs semantic) to catch template drift early
When it happens
Trigger: Generation stopped before emitting any semantic tokens (EOS-first); chat template missing the TTS prompt structure so the model answers in plain prose; tokenizer's added-special-token set lacks the bicodec tokens so decode() renders them as raw text or nothing; wrong model loaded for the requested decode path.
Common situations: Using a GGUF/quantized variant whose special tokens are not registered; prompt/prefill not ending with the audio-generation start marker; sampling params causing immediate EOS; version drift between tokenizer config and model card.
Related errors
- No valid audio codes found after START_OF_SPEECH token
- No DAC code tokens (c1/c2) found in generated output
- BiCodec dataset needs 'audio' and 'text' columns, got: {data
- No valid examples after BiCodec preprocessing (skipped {skip
- Model {self.active_model_name} is not an audio model
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/432ccfb28802654a.
Report an issue: GitHub.