microsoft/VibeVoice · critical · TypeError

acoustic_tokenizer_config has unexpected type: {type(ac_cfg)

Error message

acoustic_tokenizer_config has unexpected type: {type(ac_cfg)}

What it means

After confirming `acoustic_tokenizer_config` exists, the constructor only accepts it as an already-built VibeVoiceAcousticTokenizerConfig instance (passed through from a pre-constructed config) or as a plain dict (unpacked via **ac_cfg into the config class). Any other type — string, list, OmegaConf object, namespace, or a dataclass from a mismatched library version — raises this TypeError.

Source

Thrown at vllm_plugin/model.py:226

        if target_hidden_size is None:
            print("[VibeVoice] WARN: Could not find hidden_size in config! Defaulting to 3584 (7B).", file=sys.stderr)
            self.hidden_size = 3584
        else:
            self.hidden_size = target_hidden_size

        ac_cfg = get_cfg(config, "acoustic_tokenizer_config")
        sc_cfg = get_cfg(config, "semantic_tokenizer_config")
        
        if ac_cfg is None or sc_cfg is None:
            raise ValueError("Missing acoustic/semantic tokenizer config in model config")

        # Handle both dict and already-constructed config objects
        if isinstance(ac_cfg, VibeVoiceAcousticTokenizerConfig):
            acoustic_config = ac_cfg
        elif isinstance(ac_cfg, dict):
            acoustic_config = VibeVoiceAcousticTokenizerConfig(**ac_cfg)
        else:
            raise TypeError(f"acoustic_tokenizer_config has unexpected type: {type(ac_cfg)}")
        
        if isinstance(sc_cfg, VibeVoiceSemanticTokenizerConfig):
            semantic_config = sc_cfg
        elif isinstance(sc_cfg, dict):
            semantic_config = VibeVoiceSemanticTokenizerConfig(**sc_cfg)
        else:
            raise TypeError(f"semantic_tokenizer_config has unexpected type: {type(sc_cfg)}")
        
        # Tokenizers use float32 for numerical precision
        self.acoustic_tokenizer = VibeVoiceAcousticTokenizerModel(acoustic_config)
        self.semantic_tokenizer = VibeVoiceSemanticTokenizerModel(semantic_config)
        
        # Get audio encoder dtype from config (defaults to float32 for precision)
        root_torch_dtype = get_cfg(config, "torch_dtype", None)
        if root_torch_dtype is not None:
            if isinstance(root_torch_dtype, str):
                self._audio_encoder_dtype = getattr(torch, root_torch_dtype)
            else:

View on GitHub (pinned to 94da20d98b)

Solutions

  1. Ensure the value at `acoustic_tokenizer_config` in config.json is a JSON object (dict), not a string; if it is a string, json.loads/parse it back into a dict.
  2. If the config is an OmegaConf/namespace object, convert with OmegaConf.to_container(cfg.acoustic_tokenizer_config) (or vars(namespace)) before loading the model.
  3. Check for duplicate vibevoice installs: pip show vibevoice and python -c 'import vibevoice; print(vibevoice.__file__)' to make sure the plugin and your code import the same package.
  4. As a last resort construct the config explicitly and set it: config.acoustic_tokenizer_config = VibeVoiceAcousticTokenizerConfig(**your_dict) before engine init.

Example fix

# before (config.json, double-serialized)
"acoustic_tokenizer_config": "{\"hidden_size\": 1024, ...}"

# after
"acoustic_tokenizer_config": {"hidden_size": 1024, ...}

# before (python, OmegaConf)
cfg = OmegaConf.load("config.yaml")
# after
cfg.acoustic_tokenizer_config = OmegaConf.to_container(cfg.acoustic_tokenizer_config, resolve=True)
Defensive patterns

Strategy: validation

Validate before calling

from huggingface_hub import hf_hub_download
import json

def fetch_clean_config(repo_id: str) -> dict:
    p = hf_hub_download(repo_id, "config.json")
    cfg = json.load(open(p))
    key = "acoustic_tokenizer_config"
    v = cfg.get(key)
    if isinstance(v, str):          # double-serialized -> parse back
        cfg[key] = json.loads(v)
    assert isinstance(cfg.get(key), dict), f"{key} must be a JSON object"
    return cfg

Type guard

def is_tokenizer_cfg_dict(v) -> bool:
    if isinstance(v, str):
        import json
        try: v = json.loads(v)
        except Exception: return False
    return isinstance(v, dict)

Try / catch

try:
    llm = LLM(model=model_id)
except TypeError as e:
    if "acoustic_tokenizer_config has unexpected type" in str(e):
        raise SystemExit("Fix config.json: acoustic_tokenizer_config must be a JSON object/dict")
    raise

Prevention

When it happens

Trigger: config.json storing the section as a JSON *string* (double-serialized) instead of an object; tooling that converts nested dicts to EasyDict/AddArgs namespaces or OmegaConf DictConfig which fail isinstance(..., dict); a config object from a different vibevoice package version whose class identity (isinstance check) no longer matches the one imported by the plugin.

Common situations: OmegaConf/YACS-wrapped configs loaded by training frameworks and passed straight into the vLLM plugin; configs round-tripped through YAML tools that stringify nested maps; two copies of the vibevoice package on sys.path (pip install + local clone) making isinstance checks fail on identical-looking configs.

Related errors


AI-assisted analysis of microsoft/VibeVoice@94da20d98b (2026-08-15). Data as JSON: /api/errors/9dc4f7437b01fca4. Report an issue: GitHub.