bridge.models.conversion.peft_bridge#

Module Contents#

Classes#

_AbsentProjectionSentinel

Singleton sentinel returned by _split_qkv_linear_out_weight to declare that a projection key has no counterpart in the HF model and should be skipped during adapter export. Example: v_proj on Gemma4 global-attention layers that use K=V tying (no v_proj weight exists in HF).

AdapterWeightConversionTask

Task describing an adapter’s LoRA weights for conversion or merging.

AdapterWeight

Materialized adapter weights ready for merge.

MegatronPeftBridge

Mixin providing adapter-aware utilities for Megatron model bridges.

Functions#

_select_hf_base_param_name

Return the HF base parameter name associated with this adapter.

_is_expert_adapter_base_name

Return whether an HF LoRA base name addresses a routed-expert projection.

_expected_shared_outer_side

Return the LoRA suffix a shared-outer adapter shares for this projection, if known.

_lora_rank_of

Rank axis of an exported LoRA factor: [.., r, in] for lora_A, [.., out, r] for lora_B.

_classify_shared_outer_expert_export

Return the shared LoRA suffix of a shared-outer MoE LoRA export, or None otherwise.

infer_target_modules_from_adapter_weights

Derive HF target_modules from the HF-format adapter weight names.

_split_hf_lora_weight_name

Split an HF-format LoRA weight name into its base target path and LoRA suffix.

_order_target_parameters

Return PEFT target parameters in stable per-parent order.

_build_target_parameter_prefixes

Map PEFT target parameters to their on-disk ParamWrapper prefixes.

_pack_target_parameter_adapter_weights

Convert exported target-parameter LoRA tensors into PEFT’s ParamWrapper layout.

convert_adapter_weights_to_peft_state

Rewrite exported adapter weights into the PEFT on-disk state-dict layout.

infer_rank_pattern_from_adapter_weights

Infer PEFT rank_pattern entries from exported adapter tensors.

build_adapter_config_dict

Build an HF PEFT-compatible adapter_config.json dictionary.

Data#

API#

class bridge.models.conversion.peft_bridge._AbsentProjectionSentinel#

Singleton sentinel returned by _split_qkv_linear_out_weight to declare that a projection key has no counterpart in the HF model and should be skipped during adapter export. Example: v_proj on Gemma4 global-attention layers that use K=V tying (no v_proj weight exists in HF).

Bridges that need this behaviour should return this sentinel for the absent key so that the generic export code can distinguish an intentional skip from a bug.

__slots__#

()

__repr__() → str#
bridge.models.conversion.peft_bridge.ABSENT_PROJECTION#

‘_AbsentProjectionSentinel(…)’

bridge.models.conversion.peft_bridge.MegatronModel#

‘TypeVar(…)’

bridge.models.conversion.peft_bridge.ADAPTER_NAME_MAP#

None

bridge.models.conversion.peft_bridge.ADAPTER_KEY_TO_SUFFIX#

None

bridge.models.conversion.peft_bridge.MEGATRON_TO_HF_LORA_SUFFIX#

None

bridge.models.conversion.peft_bridge.GDN_IN_PROJ_KEYS#

(‘in_proj_qkv’, ‘in_proj_z’, ‘in_proj_b’, ‘in_proj_a’)

class bridge.models.conversion.peft_bridge.AdapterWeightConversionTask#

Task describing an adapter’s LoRA weights for conversion or merging.

global_base_prefix: str#

None

adapter_key: Optional[str]#

None

alpha: int#

None

dim: int#

None

linear_in_task: megatron.bridge.models.conversion.model_bridge.WeightConversionTask#

None

linear_out_task: megatron.bridge.models.conversion.model_bridge.WeightConversionTask#

None

requires_expert_splits: bool#

False

class bridge.models.conversion.peft_bridge.AdapterWeight#

Materialized adapter weights ready for merge.

global_base_prefix: str#

None

adapter_key: Optional[str]#

None

alpha: int#

None

dim: int#

None

linear_in_weight: megatron.bridge.models.conversion.model_bridge.MegatronWeightTuple#

None

linear_out_weight: megatron.bridge.models.conversion.model_bridge.MegatronWeightTuple#

None

bridge.models.conversion.peft_bridge._select_hf_base_param_name(
base_mapping,
adapter_key: Optional[str],
expected_suffix: str,
) → Optional[str]#

Return the HF base parameter name associated with this adapter.

class bridge.models.conversion.peft_bridge.MegatronPeftBridge#

Mixin providing adapter-aware utilities for Megatron model bridges.

_adapter_target_modules(
adapter_weight_names: Iterable[str],
) → list[str]#

Return the target_modules written to an exported adapter_config.json.

AutoBridge.save_hf_adapter calls this hook with the Hugging Face PEFT names of the exported adapter weights (for example base_model.model.model.layers.0.self_attn.q_proj.lora_A.weight). The default keeps PEFT’s usual leaf-name selectors (q_proj, gate_proj, …), inferred by

Func:

infer_target_modules_from_adapter_weights.

Override it when a leaf name is shared by modules the adapter does not cover. PEFT matches target_modules by suffix, so a bare leaf name attaches an untrained adapter to every module with that name when the adapter is loaded.

Example: Beam has an attention output gate self_attn.gate_proj and an MLP mlp.gate_proj. For an adapter trained on attention only, the default returns ["gate_proj", "k_proj", "o_proj", "q_proj", "v_proj"], which also wraps every mlp.gate_proj on load. BeamBridge returns full module paths instead::

def _adapter_target_modules(self, adapter_weight_names):
    return sorted(
        {
            _split_hf_lora_weight_name(name)[0].removeprefix("base_model.model.")
            for name in adapter_weight_names
        }
    )

which yields ["model.layers.0.self_attn.gate_proj", "model.layers.0.self_attn.q_proj", ...].

Parameters:

adapter_weight_names – Hugging Face PEFT names of the exported LoRA weights.

Returns:

Sorted target_modules entries for the PEFT adapter config.

_get_lora_unwrapped_name(megatron_param: str) → str#

Remove .to_wrap from LoRA parameter names.

_is_adapter_param_name(param_name: str) → bool#

Return True if the parameter only belongs to a PEFT adapter.

_get_adapter_wrap_module(
local_base_prefix: str,
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
vp_stage: int,
) → tuple[Optional[torch.nn.Module], Optional[torch.nn.Module]]#

Locate the adapter wrapper and its underlying module.

_resolve_hf_adapter_param_name(
mapping_registry: megatron.bridge.models.conversion.mapping_registry.MegatronMappingRegistry,
global_base_prefix: str,
megatron_adapter_suffix: str,
base_suffix: str,
adapter_key: Optional[str],
) → Optional[str]#

Resolve the HuggingFace adapter parameter name by translating the base Megatron name.

.. note::

LoRA adapters never register bias tensors for linear_in / linear_out, so callers only pass weight suffixes here. The bias fallback below is solely for robustness in case a future adapter type introduces biased projections.

_get_base_hf_param_names_for_adapter(
mapping_registry: megatron.bridge.models.conversion.mapping_registry.MegatronMappingRegistry,
global_base_prefix: str,
adapter_key: Optional[str],
base_suffix: str,
) → List[str]#

Return all HF base parameter names associated with this adapter.

_make_lora_param_name(
base_name: str,
megatron_adapter_suffix: str,
) → Optional[str]#

Translate a base HF weight name into its LoRA-specific counterpart.

_is_fused_qkv(hf_weight_names: Iterable[str]) → bool#

Check whether the provided HF names correspond to a fused QKV weight.

_is_gdn_in_proj_split(hf_weight_names: Iterable[str]) → bool#

Check whether the provided HF names correspond to split GDN in_proj weights.

_is_fused_fc1_gate_up(
base_hf_weight_names: Iterable[str],
linear_out_tensor: torch.Tensor,
base_weight_shape: Optional[torch.Size] = None,
) → bool#

Detect fused FC1 adapters based on names and tensor shape.

_infer_qkv_projection_from_name(hf_name: str) → Optional[str]#

Return q_proj/k_proj/v_proj identifier based on the HF name.

_infer_gdn_in_proj_projection_from_name(
hf_name: str,
) → Optional[str]#

Return in_proj_qkv/z/b/a identifier based on the HF name.

_is_fused_fc1_gate_proj(hf_name: str) → bool#

Return whether the HF name maps to the gate half of fused FC1.

_is_fused_fc1_up_proj(hf_name: str) → bool#

Return whether the HF name maps to the up half of fused FC1.

_infer_hf_expert_idx(hf_name: str) → Optional[int]#

Return the expert index embedded in an HF MoE weight name.

_strip_hf_expert_index(hf_name: str) → str#

Drop the experts.<idx> index from an HF MoE weight name.

A shared-outer adapter’s shared side is replicated across experts, so it is exported under the expert-agnostic name (experts.gate_proj rather than experts.0.gate_proj) that the serving loader keys its 3D-shared branch on. Mirrors :meth:_infer_hf_expert_idx’s name parsing.

_split_qkv_linear_out_weight(
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
linear_out_weight: torch.Tensor,
) → Dict[str, torch.Tensor]#

Split a fused LoRA linear_out tensor for QKV adapters.

_split_gdn_in_proj_linear_out_weight(
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
linear_out_weight: torch.Tensor,
) → Dict[str, torch.Tensor]#

Split a fused LoRA linear_out tensor for GDN in_proj adapters.

_build_lora_hf_names(
base_hf_weight_names: List[str],
) → tuple[List[str], List[str]]#

Build LoRA A/B names for a list of HF base parameter names.

_collect_packed_expert_adapter_tensors(
linear_in_tensor: torch.Tensor,
linear_out_tensor: torch.Tensor,
expert_linear_in_gathered: Optional[List[torch.Tensor]],
expert_linear_out_gathered: Optional[List[torch.Tensor]],
num_moe_experts: int,
) → tuple[List[torch.Tensor], List[torch.Tensor]]#

Collect one LoRA A/B tensor per expert for grouped expert exports.

_build_packed_expert_linear_out_by_base(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
base_hf_weight_names: List[str],
per_expert_linear_out: List[torch.Tensor],
is_expert: bool,
) → Dict[str, torch.Tensor]#

Build per-base stacked LoRA-B tensors for packed grouped-expert export.

_split_fused_fc1_linear_out_weight(
linear_out_weight: torch.Tensor,
*,
is_expert: bool,
) → tuple[torch.Tensor, torch.Tensor]#

Split fused FC1 LoRA linear_out into gate/up with TP-aware ordering.

_gather_expert_adapter_weight(
weight: torch.Tensor,
) → Optional[List[torch.Tensor]]#

Gather expert-sharded adapter weights across EP ranks when needed.

_select_expert_adapter_weight(
weight: torch.Tensor,
gathered: List[torch.Tensor],
expert_idx: int,
num_experts: int,
) → torch.Tensor#

Select the per-expert adapter weight slice if present.

_megatron_global_adapters_info_all_pp_ranks(
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
) → List[tuple[str, str, bool, bool, bool, int, int, int, int]]#

Get all adapters’ information tuple: (global_base_name, local_base_prefix, input_is_parallel, base_linear_is_parallel, requires_expert_splits, alpha, dim, pp_rank, vp_stage) across all pipeline parallel ranks.

_construct_adapters_names(
prefix: str,
adapter_key: Optional[str],
) → tuple[str, str]#

Build linear_in/linear_out parameter names for an adapter.

Parameters:
  • prefix – Base module prefix without any adapter suffix (global or local, depending on caller).

  • adapter_key – Optional adapter identifier used by CanonicalLoRA (e.g. adapter_q). None for standard single-adapter LoRA modules.

Returns:

Tuple (linear_in_name, linear_out_name) containing the parameter names for the adapter’s input and output projection weights.

build_adapter_conversion_tasks(
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
exclude_adapter_base_prefixes: Iterable[str] | None = None,
) → Dict[str, List[bridge.models.conversion.peft_bridge.AdapterWeightConversionTask]]#

Construct adapter merge tasks keyed by their base parameter.

The returned dict is keyed by the global LoRA-wrapped parameter name (e.g., decoder.layers.0.mlp.linear_fc1.to_wrap.weight). Each value contains the adapter tasks (canonical or regular) that should be merged into that base weight.

materialize_adapter_weights(
adapter_tasks: List[bridge.models.conversion.peft_bridge.AdapterWeightConversionTask],
) → List[bridge.models.conversion.peft_bridge.AdapterWeight]#

Run adapter merge tasks to gather full adapter weights.

_materialize_grouped_expert_adapter_tensor(
task: megatron.bridge.models.conversion.model_bridge.WeightConversionTask,
*,
tp_axis: int,
) → torch.Tensor#

Broadcast and gather grouped-expert adapter weights on their real expert-TP axis.

static _make_hf_weight(
megatron_param_name: Optional[str],
with_megatron_names: bool,
hf_name: str,
tensor: torch.Tensor,
) → megatron.bridge.models.conversion.model_bridge.HFWeightTuple#

Build the exported tuple, attaching the source Megatron name only when requested.

Adapter weights always come from exactly one Megatron parameter, so the sourced tuple carries a one-element megatron_param_names; a missing source (not expected on any current path) is reported as an empty tuple rather than silently dropping the flag.

stream_adapter_weights_megatron_to_hf(
megatron_model: Union[bridge.models.conversion.peft_bridge.MegatronModel, List[bridge.models.conversion.peft_bridge.MegatronModel]],
cpu: bool = True,
show_progress: bool = True,
exclude_adapter_base_prefixes: Iterable[str] | None = None,
expand_shared_outer: bool = False,
stack_3d_moe: bool = False,
with_megatron_names: bool = False,
) → Iterable[megatron.bridge.models.conversion.model_bridge.HFWeightTuple]#

Stream only adapter weights without merging them into base tensors.

Each adapter is classified into one export topology (default / packed-expert / shared-outer) by :meth:_select_adapter_emitter and emitted by the matching _emit_*_adapter method. The loop holds no per-topology logic.

stack_3d_moe emits shared-outer routed-expert LoRA as the two stacked 3D tensors vLLM’s FusedMoE3DWithLoRA consumer looks up (...experts.base_layer for gate_up_proj, bare ...experts for down_proj), instead of the per-expert 2D pack_moe layout. It is the vLLM-3D-MoE analogue of expand_shared_outer and takes precedence over it for shared-outer adapters.

with_megatron_names yields :class:HFSourcedWeightTuple values whose megatron_param_names is the one-element tuple holding the adapter’s linear_in (lora_A) or linear_out (lora_B) Megatron weight name; the default keeps the two-field :class:HFWeightTuple.

_stream_shared_outer_adapter_weights(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
mapping_registry: megatron.bridge.models.conversion.mapping_registry.MegatronMappingRegistry,
adapter_task: bridge.models.conversion.peft_bridge.AdapterWeightConversionTask,
linear_in_tensor: torch.Tensor,
linear_out_tensor: torch.Tensor,
num_moe_experts: int,
cpu: bool,
expand_shared_outer: bool,
stack_3d_moe: bool = False,
source_names: Optional[Tuple[str, str]] = None,
with_megatron_names: bool = False,
) → Iterable[megatron.bridge.models.conversion.model_bridge.HFWeightTuple]#

Stream a shared-outer grouped-expert LoRA adapter (SGLang PR #21466).

One side is a 2D LoRA matrix shared across experts; the other is a per-expert 3D pack. By default the shared side is emitted once as a [1, ...] tensor under the expert-agnostic HF name. With expand_shared_outer, it is replicated under per-expert 2D names (vLLM 2D pack_moe contract); the training-side parameter stays shared.

With stack_3d_moe, the whole adapter is emitted as the two stacked 3D tensors vLLM’s 3D-MoE consumer (FusedMoE3DWithLoRA) looks up: ...experts.base_layer (gate_up_proj) and bare ...experts (down_proj), with axis order lora_A=(E, r, in) and lora_B=(out, r, E). This is the vLLM-3D-MoE analogue of the 2D expand_shared_outer path and is required for 3D-MoE models (is_3d_moe_weight=True) that are not using vLLM’s 2D mixed MoE LoRA format.

_stream_shared_outer_adapter_weights_3d_moe(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
mapping_registry: megatron.bridge.models.conversion.mapping_registry.MegatronMappingRegistry,
adapter_task: bridge.models.conversion.peft_bridge.AdapterWeightConversionTask,
linear_in_tensor: torch.Tensor,
linear_out_tensor: torch.Tensor,
num_moe_experts: int,
cpu: bool,
is_expert: bool,
source_names: Optional[Tuple[str, str]] = None,
with_megatron_names: bool = False,
) → Iterable[megatron.bridge.models.conversion.model_bridge.HFWeightTuple]#

Emit a shared-outer routed-expert LoRA adapter in vLLM 3D-MoE layout.

vLLM’s 3D-MoE LoRA consumer (FusedMoE3DWithLoRA → _stack_moe_lora_weights) looks up exactly two stacked 3D tensors per registered ...experts module:

  • ...experts.base_layer.lora_{A,B}.weight — gate_up_proj (gate+up fused)

  • ...experts.lora_{A,B}.weight — down_proj (bare)

with axis order lora_A=(E, r, in) and lora_B=(out, r, E). The per-expert 2D names emitted by the expand_shared_outer path never match, so vLLM silently drops the routed-expert LoRA. This stacks the full global expert set (num_moe_experts) into those two 3D tensors; vLLM EP-slices [expert_start:expert_end] at load time, so the global stack is a no-op for non-EP and correct for EP.

Each adapter task is either FC1 (gate_up → base_layer) or FC2 (down → bare), distinguished by the HF base weight names it resolves to. A fused FC1 linear_out carries gate+up on its output dim already, matching vLLM’s 2*moe_intermediate w13 fused stack, so no gate/up re-split is needed.

_get_fused_adapter_linear_out_slices(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
base_hf_weight_names: List[str],
linear_out_tensor: torch.Tensor,
is_expert: bool = False,
) → Optional[Dict[str, torch.Tensor]]#

Return per-base-name linear_out slices for fused adapters, else None.

This supports fused QKV adapters (split into q/k/v) and fused FC1 adapters (split into gate/up along dim=0). The returned dict is keyed by the HF base weight name (e.g. ...q_proj.weight or ...gate_proj.weight).

_merge_lora_adapter_weights(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
converted_weights_dict: Dict[str, torch.Tensor],
adapter_weights: List[bridge.models.conversion.peft_bridge.AdapterWeight],
) → Dict[str, torch.Tensor]#

Merge LoRA adapter weights back into the base tensor for HF export.

_merge_grouped_export_adapter_weights(
task: megatron.bridge.models.conversion.model_bridge.WeightConversionTask,
converted_weights_dict: Dict[str, torch.Tensor],
adapter_weights: List[bridge.models.conversion.peft_bridge.AdapterWeight],
num_moe_experts: int,
) → Dict[str, torch.Tensor]#

Merge LoRA weights into a single grouped-expert export shard.

Grouped expert mappings bypass the standard export path and therefore never reach _merge_lora_adapter_weights. Merge the current expert’s adapter slice into its per-expert tensor before the grouped export code stacks all experts back together.

_merge_single_adapter_weight(
base_weight: torch.Tensor,
alpha: int,
dim: int,
linear_in_weight: torch.Tensor,
linear_out_weight: torch.Tensor,
) → torch.Tensor#

Merge a single adapter’s weights with base weight.

The merge is performed in float32 to avoid precision loss from bfloat16 matmul (adapter weights are often stored in bf16). The result is cast back to the original base weight dtype.

_merge_canonical_adapter_from_weights(
megatron_model: List[bridge.models.conversion.peft_bridge.MegatronModel],
converted_weights_dict: Dict[str, torch.Tensor],
adapter_weights: List[bridge.models.conversion.peft_bridge.AdapterWeight],
) → Dict[str, torch.Tensor]#

Merge CanonicalLoRA adapters using pre-materialized adapter weights.

bridge.models.conversion.peft_bridge._HF_LORA_SUFFIXES#

(‘.lora_A.weight’, ‘.lora_B.weight’)

bridge.models.conversion.peft_bridge._SHARED_OUTER_LORA_A_PROJECTIONS#

‘frozenset(…)’

bridge.models.conversion.peft_bridge._SHARED_OUTER_LORA_B_PROJECTIONS#

‘frozenset(…)’

bridge.models.conversion.peft_bridge._is_expert_adapter_base_name(base_name: str) → bool#

Return whether an HF LoRA base name addresses a routed-expert projection.

bridge.models.conversion.peft_bridge._expected_shared_outer_side(base_name: str) → Optional[str]#

Return the LoRA suffix a shared-outer adapter shares for this projection, if known.

bridge.models.conversion.peft_bridge._lora_rank_of(lora_suffix: str, tensor: torch.Tensor) → int#

Rank axis of an exported LoRA factor: [.., r, in] for lora_A, [.., out, r] for lora_B.

bridge.models.conversion.peft_bridge._classify_shared_outer_expert_export(
base_name: str,
weights: Dict[str, torch.Tensor],
module_weights: Dict[str, torch.Tensor],
) → Optional[str]#

Return the shared LoRA suffix of a shared-outer MoE LoRA export, or None otherwise.

Shared-outer expert LoRA shares lora_A on the first expert projection (gate/up) and lora_B on the second (down). The shared factor is exported once as a [1, ...] tensor under the expert-agnostic HF name; its per-expert partner is either the numbered 2D slices of the default layout (...experts.N.<proj>) or an [E, ...] stack under the same expert-agnostic name. A regular per-expert export (equal expert dims on both sides) returns None and stays on the PEFT target_parameters packing path.

Raises:

ValueError – for layouts that are neither – unequal expert dims with no side equal to 1, the shared factor on the wrong side, a rank mismatch between the two sides, or a shared factor without any per-expert partner.

bridge.models.conversion.peft_bridge.infer_target_modules_from_adapter_weights(
adapter_weight_names: Iterable[str],
) → List[str]#

Derive HF target_modules from the HF-format adapter weight names.

Given names like model.layers.0.self_attn.q_proj.lora_A.weight, this extracts the unique module identifiers (q_proj, gate_proj, …) that the peft library expects in adapter_config.json.

bridge.models.conversion.peft_bridge._split_hf_lora_weight_name(name: str) → tuple[str, str]#

Split an HF-format LoRA weight name into its base target path and LoRA suffix.

bridge.models.conversion.peft_bridge._order_target_parameters(
target_parameters: List[str],
) → List[str]#

Return PEFT target parameters in stable per-parent order.

bridge.models.conversion.peft_bridge._build_target_parameter_prefixes(
target_parameters: List[str],
) → Dict[str, str]#

Map PEFT target parameters to their on-disk ParamWrapper prefixes.

bridge.models.conversion.peft_bridge._pack_target_parameter_adapter_weights(
lora_a: torch.Tensor,
lora_b: torch.Tensor,
) → tuple[torch.Tensor, torch.Tensor]#

Convert exported target-parameter LoRA tensors into PEFT’s ParamWrapper layout.

Exported factors are lora_A [E, r, in] and lora_B [E, out, r]. ParamWrapper reads lora_A as (E, r, in) and lora_B as (out, r, E), so the columns of the packed lora_B must be expert-fastest.

bridge.models.conversion.peft_bridge.convert_adapter_weights_to_peft_state(
adapter_weights: Iterable[megatron.bridge.models.conversion.model_bridge.HFWeightTuple],
*,
allow_serving_layout: bool = False,
) → tuple[Dict[str, torch.Tensor], List[str], List[str]]#

Rewrite exported adapter weights into the PEFT on-disk state-dict layout.

This follows the original adapter export flow as closely as possible: trust the exported HF names, write normal 2D LoRA tensors directly under base_model.model.*, and only special-case 3D tensors because PEFT stores packed parameter targets through ParamWrapper.

A shared-outer MoE LoRA (one factor shared across experts, the other per-expert) has no ParamWrapper representation, so PeftModel.from_pretrained cannot load it. By default such an export raises; with allow_serving_layout=True both sides are written exactly as exported (the shared factor once as [1, ...] under the expert-agnostic name, next to its per-expert partner), which is the layout serving stacks keyed on the leading expert dim (SGLang experts_shared_outer_loras) read.

bridge.models.conversion.peft_bridge.infer_rank_pattern_from_adapter_weights(
adapter_weights: Iterable[megatron.bridge.models.conversion.model_bridge.HFWeightTuple],
*,
default_rank: int,
) → Dict[str, int]#

Infer PEFT rank_pattern entries from exported adapter tensors.

bridge.models.conversion.peft_bridge.build_adapter_config_dict(
peft_config: megatron.bridge.peft.base.PEFT,
target_modules: List[str],
target_parameters: Optional[List[str]] = None,
base_model_name_or_path: Optional[str] = None,
rank_pattern: Optional[Dict[str, int]] = None,
) → Dict[str, object]#

Build an HF PEFT-compatible adapter_config.json dictionary.

The returned dict can be serialised directly with json.dump and is loadable by peft.PeftModel.from_pretrained without any runtime dependency on the peft pip package.