hiyouga/LlamaFactory · error · AttributeError

The model does not have a submodule named '{submodule_name}'

Error message

The model does not have a submodule named '{submodule_name}'.

What it means

HyperParallel context parallelism repeats each logical batch across CP ranks via _CPBatchRepeatedBatchSampler, which requires integer indexing into the dataset (trainer.py:257). Iterable datasets (streaming datasets) can only be consumed sequentially, so _get_cp_dataloader raises NotImplementedError for torch.utils.data.IterableDataset before training starts.

Source

Thrown at scripts/qwen_omni_merge.py:60

):
    """Load the original model, merge the LoRA weights.

    For a specified submodule, and save the final merged model along with its configurations.

    Args:
        model_path (str): Path to the original model directory.
        lora_path (str): Path to the directory containing LoRA weights.
        save_path (str): Directory where the merged model and configurations will be saved.
        extra_file (str): Name of the extra file to be copied (default: "spk_dict.pt").
        submodule_name (str): Name of the submodule to merge (default: "thinker").
    """
    # 1. Load the original model
    model = AutoModelForTextToWaveform.from_pretrained(model_path, torch_dtype="auto", device_map="cpu")
    print("Successfully loaded the original model.")

    # 2. Extract the submodule to be merged (e.g., model.thinker)
    if not hasattr(model, submodule_name):
        raise AttributeError(f"The model does not have a submodule named '{submodule_name}'.")

    base_submodule = getattr(model, submodule_name)
    print(f"Successfully extracted submodule: {submodule_name}.")

    # 3. Load the LoRA weights onto the extracted submodule
    lora_model = PeftModel.from_pretrained(base_submodule, lora_path)
    processor = AutoProcessor.from_pretrained(lora_path)
    print("Successfully loaded LoRA weights and processor.")

    # 4. Merge the LoRA weights into the submodule and unload the LoRA modules
    merged_submodule = lora_model.merge_and_unload()
    print("Successfully merged LoRA weights.")

    # 5. Replace the original submodule with the merged submodule in the model
    setattr(model, submodule_name, merged_submodule)

    # 6. Save the final merged model along with the tokenizer and processor configuration
    model.save_pretrained(save_path)

View on GitHub (pinned to f28afaf635)

Solutions

  1. Use a map-style dataset: download/materialize the data and set streaming: false in dataset_info.json so a datasets.Dataset (map-style) is passed
  2. Or set hyper_parallel_cp_size: 1 to disable CP, after which IterableDataset works through the normal trainer path

Example fix

# before (dataset_info.json)
"my_data": {"file_name": "...", "streaming": true}
# with hyper_parallel_cp_size: 2 -> NotImplementedError

# after
"my_data": {"file_name": "...", "streaming": false}
Defensive patterns

Strategy: validation

Validate before calling

import torch.utils.data as tud
assert not isinstance(train_dataset, tud.IterableDataset) or hp_args.cp_size <= 1, (
    'HyperParallel CP (cp_size>1) needs a map-style dataset; disable streaming or set cp_size=1'
)

Type guard

def dataset_is_map_style(dataset) -> bool:
    import torch.utils.data as tud
    return not isinstance(dataset, tud.IterableDataset)

Try / catch

try:
    trainer.train()
except NotImplementedError as e:
    if 'map-style dataset' in str(e):
        raise SystemExit('Set streaming:false in dataset_info.json or set hyper_parallel_cp_size:1') from e
    raise

Prevention

When it happens

Trigger: hyper_parallel_cp_size > 1 combined with a streaming dataset (dataset_info entry with streaming: true, or an IterableDataset handed to the trainer); get_train_dataloader routes into _get_cp_dataloader which refuses IterableDataset.

Common situations: Training on huge streamed corpora to avoid disk usage while enabling CP; switching a working streaming SFT config to the HyperParallel path.

Related errors


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