hiyouga/LlamaFactory · error · ValueError

YAML config must be a dictionary mapping tokens to descripti

Error message

YAML config must be a dictionary mapping tokens to descriptions. Got: {type(token_descriptions)}

What it means

Raised in ModelArguments.__post_init__ (model_args.py:224) when new_special_tokens_config points to a YAML file whose top-level structure is not a mapping of token -> description. The config is loaded with OmegaConf and converted with to_container; if the result is a list, scalar, or null (e.g. the file contains only a '- token' list or a bare string), the isinstance(dict) check fails and this ValueError is raised during argument parsing.

Source

Thrown at src/llamafactory/hparams/model_args.py:224

    def __post_init__(self):
        if self.model_name_or_path is None:
            raise ValueError("Please provide `model_name_or_path`.")

        if self.adapter_name_or_path is not None:  # support merging multiple lora weights
            self.adapter_name_or_path = [path.strip() for path in self.adapter_name_or_path.split(",")]

        if self.add_tokens is not None:  # support multiple tokens
            self.add_tokens = [token.strip() for token in self.add_tokens.split(",")]

        # Process special tokens with priority: new_special_tokens_config > add_special_tokens
        if self.new_special_tokens_config is not None:
            # Priority 1: Load from YAML config (extracts both tokens and descriptions)
            try:
                cfg = OmegaConf.load(self.new_special_tokens_config)
                token_descriptions = OmegaConf.to_container(cfg)

                if not isinstance(token_descriptions, dict):
                    raise ValueError(
                        f"YAML config must be a dictionary mapping tokens to descriptions. "
                        f"Got: {type(token_descriptions)}"
                    )

                # Extract token list from config keys
                extracted_tokens = list(token_descriptions.keys())

                # Warn if both are set
                if self.add_special_tokens is not None:
                    logger.warning_rank0(
                        "Both 'new_special_tokens_config' and 'add_special_tokens' are set. "
                        f"Using tokens from config: {extracted_tokens}"
                    )

                # Override add_special_tokens with extracted tokens (as list)
                self.add_special_tokens = extracted_tokens

                # Store descriptions internally for later use (internal attribute)

View on GitHub (pinned to f28afaf635)

Solutions

  1. Rewrite the YAML as a mapping: each top-level key is the token string, its value the description
  2. Example: '<|im_start|>': 'start of turn' as top-level entries, no leading dashes
  3. If you only need tokens without descriptions, use the simpler add_special_tokens: '<tok1>,<tok2>' comma-separated string instead

Example fix

# before (specials.yaml)
- <|im_start|>
- <|im_end|>

# after (specials.yaml)
'<|im_start|>': 'start of turn'
'<|im_end|>': 'end of turn'
Defensive patterns

Strategy: type-guard

Validate before calling

from omegaconf import OmegaConf
cfg_doc = OmegaConf.to_container(OmegaConf.load(path))
assert isinstance(cfg_doc, dict), 'special tokens YAML must be a token->description mapping'

Type guard

def is_token_mapping(v: object) -> bool:
    return isinstance(v, dict) and all(isinstance(k, str) for k in v)

Try / catch

try:
    args = ModelArguments(**cfg)
except ValueError as e:
    if 'YAML config must be a dictionary' in str(e):
        rewrite_list_to_mapping(path)  # '- tok' -> "'tok': desc"
        args = ModelArguments(**cfg)
    else:
        raise

Prevention

When it happens

Trigger: new_special_tokens_config: specials.yaml where specials.yaml contains a YAML list of tokens or plain text instead of key: value pairs; an empty YAML file (to_container gives None); a JSON file whose top level is an array.

Common situations: Users writing a token list (the intuitive format) instead of a mapping; reusing the same file for add_special_tokens (comma string) and the config variant; hand-editing that accidentally deletes the mapping structure.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/8211a01e9eb9cfc3. Report an issue: GitHub.