/** * import/foreign/plan.ts — the ONE executor for a foreign-checkpoint weight port. * * A port is expressed declaratively: every target parameter of this engine's * {@link HybridMambaModel} gets exactly one {@link PortRule} saying which source * tensor feeds it and how the bytes are reshaped. Architecture adapters * (`falcon_mamba.ts`, `codestral_mamba.ts`) only *describe* their rules — the * matching, validation and transform logic lives here once, so a new * architecture never re-implements it. * * The contract that makes a port trustworthy: NOTHING is silently dropped. * • a target with no source in the checkpoint is a `fill` rule and is reported * in {@link PortedCheckpoint.synthesisedTargets}; * • a source tensor no rule consumed is reported in * {@link PortedCheckpoint.unmappedSources}; * • a source tensor only PARTLY consumed (e.g. Mamba-2's gate rows, which this * engine's block has no branch for) is declared as a {@link PortDiscard}; * • a shape that doesn't line up throws, naming the tensor and both shapes. */ import type { NamedTensor } from "../../export/tensors.js"; /** * How one source tensor becomes one target buffer. * * • `copy` — element-for-element; source and target shapes must * agree once size-1 axes are squeezed out. Linear * weights need no transpose: HF stores * `[out_features, in_features]` row-major and this * engine's LINEAR_FORWARD_WGSL reads `W` as `(N, K)` * = `[out, in]` row-major — the same layout. * • `convTaps` — a depthwise conv kernel `[C, 1, K]` (PyTorch * `nn.Conv1d(groups=C)`) → `[C, K]` with the taps * REVERSED. PyTorch pads left by `K-1` and cross- * correlates: `y[t] = Σ_j w[j]·x[t + j - (K-1)]`, * while conv1d.ts computes * `y[t] = Σ_k w[k]·x[t - k]`. Substituting * `k = K-1-j` shows the two agree only when the tap * axis is reversed. * • `rowSlice` — keep rows `[start, start+count)` of a rank-2 * source. Used for Mamba-2's fused `in_proj`. * • `fill` — no source: fill the target with a constant. * • `negExpToSoftplusInv` — `A_log` convention change. HF Mamba-2 uses * `A = -exp(A_log)`; this engine's SSD kernel uses * `A = -softplus(A_log)`. Re-express the same `A`: * `target = softplus⁻¹(exp(source))`. */ export type PortOp = { kind: "copy"; } | { kind: "convTaps"; } | { kind: "rowSlice"; start: number; count: number; } | { kind: "fill"; value: number; } | { kind: "negExpToSoftplusInv"; }; /** How ONE target parameter of this engine is produced. */ export interface PortRule { /** Target parameter name, exactly as `HybridMambaModel.parameters()` names it. */ target: string; /** Expected target shape (row-major), for validation and reporting. */ shape: number[]; /** * Candidate source tensor names, in preference order — the first one present * in the checkpoint is used. Empty means the target is synthesised (`fill`), * because this architecture has no such tensor. */ from: string[]; op: PortOp; /** Why this isn't a plain copy / why there is no source. Required for `fill`. */ note?: string; } /** A source tensor deliberately consumed only in part. */ export interface PortDiscard { source: string; /** How many source elements are left behind. */ elements: number; reason: string; } /** The complete, architecture-specific description of a port. */ export interface PortPlan { /** Adapter id, e.g. `falcon_mamba`. */ adapter: string; rules: PortRule[]; discards: PortDiscard[]; } /** A target that no source tensor feeds, and the constant used instead. */ export interface SynthesisedTarget { target: string; value: number; reason: string; } /** The result of running a {@link PortPlan} over a checkpoint's tensors. */ export interface PortedTensors { adapter: string; /** Target parameter name → buffer, sized exactly as the model expects. */ weights: Map; /** Checkpoint tensors that no rule consumed (e.g. an untied `lm_head.weight`). */ unmappedSources: string[]; /** Targets this architecture has no tensor for. */ synthesisedTargets: SynthesisedTarget[]; /** Source tensors consumed only in part. */ discardedSources: PortDiscard[]; } /** * Mistral publishes the same Mamba-2 weights twice: the HF conversion * (`backbone.…`) and its native `consolidated.safetensors`, whose names carry a * `model.` prefix. Strip it so one rule table serves both. The * `embedding`/`embeddings` spelling difference is handled by the rules' `from` * alternatives, not here. */ export declare function normaliseSourceName(name: string): string; /** * Execute a plan against a checkpoint's tensors. Every rule must resolve; the * first failure throws naming the offending tensor. Sources no rule touched are * returned rather than ignored. */ export declare function executePortPlan(plan: PortPlan, tensors: NamedTensor[]): PortedTensors; //# sourceMappingURL=plan.d.ts.map