quantize HuBERT vectors to bark semantic tokens
Where a voice becomes a speaker
- quantizer_model
- vectors
- semantic_tokens
The last piece of the voice-cloning puzzle. bark_hubert_quantize takes the continuous HuBERT vectors from bark_hubert_encode and runs them through the quantizer loaded by load_bark_hubert_quantizer, producing Bark's semantic tokens. That's the moment a reference voice officially becomes something you can feed into Bark's generation chain - or save into a speaker .npz.
How it works
Inside the quantizer, each 768-dimensional vector passes through a two-layer LSTM followed by a linear layer that scores all 10,000 semantic tokens, and the node takes the argmax - the single most likely token for each vector. It's a hard quantization: continuous "how does this sound" becomes a discrete index Bark's semantic model understands. That's also why it's fast and why it's one-way - you can't recover the vectors from the tokens, and you don't need to.
Inputs & outputs
- quantizer_model - from
load_bark_hubert_quantizer. - vectors - from
bark_hubert_encode.
The output, semantic_tokens (BarkSemanticTokens), is the semantic prompt for a speaker file: wire it into save_speaker_npz's semantic_prompt input alongside the coarse and fine prompts from the encodec chain, and you've got a complete .npz that load_speaker_npz can bring back later.
Install & the fine print
Pack install, standard:
cd ComfyUI/custom_nodes
git clone https://github.com/gitmylo/ComfyUI-audio-nodes
(or ComfyUI Manager β "Audio nodes"), restart.
Two practical notes. First, the layer/quantizer pairing is everything: bark_hubert_encode defaults to layer 9, and you want the quantizer that was trained on layer 9 - if you grabbed quantifier_hubert_base_ls960_14.pth from the loader dropdown thinking "newer default = better," the mismatch will quietly degrade your cloning. Second, because quantization is argmax (greedy, no temperature), it's deterministic - the same clip always yields the same tokens, which is what you want when building a speaker file you'll reuse. That determinism is also the honest limit of the whole approach: the speaker is only as good as the reference clip, and HuBERT-to-token is a lossy translation. Clean 5β10 second clip, one speaker, no music, and you'll get a usable voice anchor; anything messier and you'll be fighting the source material the whole way down.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| quantizer_model | BarkHuBERTQuantizerModel | β | |
| vectors | HuBERTVectors | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| semantic_tokens | BarkSemanticTokens | β |