huggingface/transformers · error · ValueError

Multiple different capturing groups found in target_patterns

Error message

Multiple different capturing groups found in target_patterns: {unique_capturing_groups}. All target patterns must use the same capturing group pattern.

What it means

Raised in WeightTransform.__init__ (core_model_loading.py:809) while validating regex capturing groups. Target patterns may carry at most ONE distinct capturing-group pattern across the whole list (e.g. all targets use the same '(\d+)' style group), because reverse mapping substitutes matched group content back into source patterns via a single \1 backreference. If two target patterns use different capturing groups, the reverse mapping becomes ambiguous and init fails.

Source

Thrown at src/transformers/core_model_loading.py:809

        self.base_model_prefix: str | None = None

        # We need to process a few exceptions here when instantiating the reverse mapping (i.e. the targets become
        # sources, and sources become targets). The issues lie in the sources usually, so here we need to check the
        # targets for the reversed mapping

        # Process target_patterns: detect capturing groups and replace with \1
        # Store the original capturing group patterns for reverse mapping
        target_capturing_groups: list[str] = []
        for i, pattern in enumerate(self.target_patterns):
            self.target_patterns[i], captured_group = process_target_pattern(pattern)
            if captured_group is not None:
                target_capturing_groups.append(captured_group)

        # Validate that we only have one unique capturing group pattern across all targets
        # This ensures deterministic reverse mapping when sources have \1 backreferences
        unique_capturing_groups = set(target_capturing_groups)
        if len(unique_capturing_groups) > 1:
            raise ValueError(
                f"Multiple different capturing groups found in target_patterns: {unique_capturing_groups}. "
                f"All target patterns must use the same capturing group pattern."
            )
        unique_capturing_group = unique_capturing_groups.pop() if unique_capturing_groups else None

        # We also need to check capturing groups in the sources during reverse mapping (e.g. timm_wrapper, sam3)
        for i, pattern in enumerate(self.source_patterns):
            # Replace capturing groups
            if r"\1" in pattern:
                if unique_capturing_group is None:
                    raise ValueError(
                        f"Source pattern '{pattern}' contains \\1 backreference, but no capturing groups "
                        f"found in target_patterns."
                    )
                # Use the unique capturing group from target_patterns for all sources
                pattern = pattern.replace(r"\1", unique_capturing_group, 1)
            # Potentially process a bit more for consistency - only if they are consistent pairs, i.e. the length is the same
            if len(self.source_patterns) == len(self.target_patterns):

View on GitHub (pinned to a597f97485)

Solutions

  1. Make every target pattern use the IDENTICAL capturing group substring (same regex text inside the parentheses).
  2. Replace extra variation with non-capturing groups (?:...) or plain literals.
  3. If two genuinely different group structures are needed, split into two separate WeightTransform/WeightConverter instances.

Example fix

# before
WeightTransform(source_patterns=[r'blk.(\d+).*'], target_patterns=[r'layers.(\d+)', r'layers.attn.(\d+.\w+)'])

# after: single shared capturing group shape
WeightTransform(source_patterns=[r'blk.(\d+).*'], target_patterns=[r'layers.\1.q_proj', r'layers.\1.k_proj'])
Defensive patterns

Strategy: validation

Validate before calling

groups = {m.group(1) for p in target_patterns if (m := re.search(r'\((?!\?:)[^)]*\)', p))}
assert len(groups) <= 1, f'multiple distinct capturing groups: {groups} — unify them or split into two transforms'

Prevention

When it happens

Trigger: Constructing a WeightTransform/WeightConverter where target_patterns = [r'layers.(\d+).q_proj', r'model.layers.(\d+.attn).k_proj'] — i.e. two different capturing-group shapes. Also triggered by patterns with multiple nested groups in different arrangements across targets.

Common situations: Hand-writing conversion recipes for multi-layer models; authors naturally write per-layer regexes and accidentally vary the group structure (e.g. one target captures the index, another captures 'index.attn'). Usually a recipe-authoring bug caught at import/init time.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/7ad583927afe07ec. Report an issue: GitHub.