Skip to content

Enabling Dissag Infra for weightfree + TODO addressed - #1345

Open
quic-amitraj wants to merge 15 commits into
quic:mainfrom
amarquic:updated_checkpoint_design
Open

quic-amitraj wants to merge 15 commits into
quic:mainfrom
amarquic:updated_checkpoint_design

Conversation

@quic-amitraj

Copy link
Copy Markdown
Contributor

No description provided.

@quic-amitraj quic-amitraj changed the title Enabling Dissag Infra for weightfree+t TODO addressed Enabling Dissag Infra for weightfree + TODO addressed Sep 16, 2026
@quic-amitraj quic-amitraj added the qeff.weightfree WeightFree Onnx Export based on Dyanmo and Meta state label Sep 16, 2026
@quic-amitraj
quic-amitraj marked this pull request as ready for review September 16, 2026 06:05
del initializers[name]


def _prepared_checkpoint_hash(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include moe_prefill_num_pipeline_stages and
moe_prefill_num_parallelized_experts here. Two expert_parallel
exports of the same model and dtype but different P/E values
produce different packed tensor shapes, but this key sends
both to the same prepared directory and manifest, so the
second export can silently reuse incompatible weights.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +200 to +207
_ID_MAP = {
"moe_expert_stacking_v1": MoEExpertStackingCheckpointTransform,
"gptoss_mxfp4_dequant_v1": GptOssMxfp4ExpertDequantSplitCheckpointTransform,
"fused_expert_split_v1": FusedExpertSplitCheckpointTransform,
"moe_fused_expert_split_v1": FusedExpertSplitCheckpointTransform,
"granite_moe_fused_split_v1": FusedExpertSplitCheckpointTransform,
"dtype_conversion_v1": DtypeConversionCheckpointTransform,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the expert-parallel transform IDs here, even if
they resolve to the unconfigured base classes for key lookup.
The manifest can now record moe_expert_parallel_stacking_v1 or
gptoss_mxfp4_dequant_expert_parallel_v1, but this lookup
cannot resolve either, so
promote_initializers_and_build_spec() loses the active
transform and per-expert .mlp. ONNX names no longer map
to .block_sparse_moe. checkpoint keys.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Comment on lines -343 to -349
if len(scatter_nodes) != 2:
logger.debug(
"PreserveNestedCacheRetainedStateTransform: function '%s' has %d scatter node(s), expected 2 — skipping.",
node.op_type,
len(scatter_nodes),
)
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this removed?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition doesn't make sense for prefill moe if you see this hardcoded the number of scatter node to 2 but for prefill with expert parallel, we have more than 2 operator ctx_nodes then it will not apply this onnx transform and which raise compiler error. Now even if we remove this condition below
scatter_nodes.sort(key=cls._scatter_sort_key) # Only the first two scatter outputs map to key / value respectively. scatter_outputs = [n.output[0] for n in scatter_nodes[:2]]

we sort and select top 2 which is required for the retain_state renaming which work perfectly fine. So the condition was redundant previously.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are some models that might have single KV instead of two like deepseek there we want only first scatter output to map to KV cache for MLA. We may need to handle that when we enable deepseek models. Can you put this as a TODO here.

Comment thread QEfficient/transformers/moe/flavours.py Outdated
# NOTE: expand_as(...) instead of torch.full_like(...) is the compiler-preferred
# workaround for ConstantOfShape(INT32_MAX); both produce identical traced Ctx ops.
matched_idx = int32_max_scalar.expand_as(token_idx)
matched_idx = int32_max_scalar

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was intentional, did you check the NOTE? why remove this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert the changes. I was changing the torch.tensor() to torch.full_like() that was the follow up changes. I reverted this .

@ochougul ochougul left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 1345 Checkpoint Pipeline Refactor Plan

Goal

Replace the current checkpoint-transform selector/consumed-key model with a real planning and execution pipeline for
weight-free checkpoint preparation.

The design must support:

  • multiple transforms applied to the same logical tensor
  • transforms that require a group of keys before they can run
  • one source read path and one final write path where possible
  • bounded RAM usage while still parallelizing independent work
  • centralized checkpoint finalization: sidecars, index, manifest, sentinel

Current Problem

PR 1345 changes the old selector into a staged flow, but it still uses a consumed set:

for transform in transforms_to_run:
    remaining = {k: v for k, v in weight_map.items() if k not in consumed}
    result = transform.apply(src, out, target_dtype=target_dtype, weight_map=remaining)
    consumed.update(transform.get_consumed_keys(weight_map))

This means each raw key is effectively owned by one transform. That cannot model cases where the same logical tensor
needs multiple stages:

raw expert keys -> stack/dequant/split -> expert_parallel pack -> dtype/final output

The current workaround is to create special combined transform subclasses, but that does not scale and does not fully
address the pipeline TODO.

Target Model

Use a two-phase design:

  1. Planning phase

    • inspect weight_map, model config, hash_params, and target dtype
    • build explicit checkpoint tasks
    • identify dependencies between tasks
    • estimate peak RAM per task
    • derive the prepared-checkpoint cache key from the full plan
  2. Execution phase

    • run ready tasks through a shared thread pool
    • submit tasks only when estimated RAM budget allows
    • load required tensors once for the task
    • run all compatible transform stages in memory
    • write final tensors once
    • release tensors immediately
    • collect final weight_map

Core Types

Add small internal planning types, probably in QEfficient/base/checkpoint_transforms.py or a nearby internal module.

from dataclasses import dataclass


@dataclass(frozen=True)
class TensorRef:
    key: str
    stage: str


@dataclass(frozen=True)
class TaskParams:
    transform_id: str
    values: tuple[tuple[str, object], ...]


@dataclass
class CheckpointTask:
    task_id: str
    input_refs: tuple[TensorRef, ...]
    output_refs: tuple[TensorRef, ...]
    source_files: tuple[str, ...]
    output_file: str
    estimated_peak_bytes: int
    params: TaskParams

    def run(self, src: Path, out: Path, target_dtype: torch.dtype) -> dict[str, str]:
        ...

TensorRef.stage is important. It distinguishes:

("model.layers.0.moe_weights.gate", "stacked")
("model.layers.0.moe_weights.gate", "packed")
("model.layers.0.moe_weights.gate", "final")

Without staged tensor refs, a plain key-to-transform map cannot represent multiple transforms on one logical key.

Transform Contract

Replace or supplement the current apply() / get_consumed_keys() contract with planning:

class BaseCheckpointTransform:
    TRANSFORM_ID: str = ""

    @classmethod
    def plan_tasks(
        cls,
        weight_map: dict[str, str],
        config,
        hash_params: dict,
        target_dtype: torch.dtype,
    ) -> list[CheckpointTask]:
        ...

Transforms should declare task groups. The pipeline should own scheduling, loading, writing, and finalization.

Task Shapes

Dense / Base Dtype Conversion

Use independent shard-level or key-group tasks:

input:  raw base keys from one shard
output: final same keys
run:    load -> dtype convert if needed -> write base shard

These tasks can run immediately and in parallel, subject to RAM budget.

Per-Expert MoE Stacking

Use one grouped task per layer:

input:  all expert projection keys for that layer
output: moe_weights.gate, moe_weights.up, moe_weights.down
run:    load all required expert tensors -> stack -> optional pack -> dtype/final -> write one layer shard

The task must validate that all required experts/projections are present before execution.

GPT-OSS MXFP4 Dequant + Split

Use one grouped task per layer:

input:  gate_up/down blocks, scales, optional biases
output: canonical moe_weights.*
run:    load blocks/scales/biases -> dequant -> split -> optional pack -> dtype/final -> write one layer shard

Fused Expert Split

Use one grouped task per layer or per fused tensor prefix:

input:  gate_up_proj, down_proj, optional biases
output: canonical moe_weights.*
run:    load fused tensors -> split -> optional pack -> dtype/final -> write final shard

Expert-Parallel Packing

Do not write this as a separate intermediate disk stage.

When hash_params["moe_prefill_flavour"] == "expert_parallel", fold packing into the grouped task execution after
stack/dequant/split and before final write:

raw group -> canonical moe_weights -> expert_parallel packed moe_weights -> final write

This avoids:

  • writing temporary stacked shards
  • reading those shards again for packing
  • growing disk usage
  • creating cleanup/staleness problems

Memory-Bounded Execution

Add a scheduler that accepts planned tasks and a memory budget.

Default budget:

max_ram_bytes = int(available_ram_gb() * 0.8 * 1024**3)

Allow an internal override later if needed, but keep the first implementation simple.

Scheduler behavior:

pending = list(tasks)
running = {}
available_refs = set(raw_refs)
active_bytes = 0

while pending or running:
    for task in ready_tasks(pending, available_refs):
        if active_bytes + task.estimated_peak_bytes <= max_ram_bytes:
            future = executor.submit(task.run, src, out, target_dtype)
            running[future] = task
            active_bytes += task.estimated_peak_bytes
            pending.remove(task)

    completed_future = wait_for_one_future(running)
    task = running.pop(completed_future)
    active_bytes -= task.estimated_peak_bytes
    final_weight_map.update(completed_future.result())
    available_refs.update(task.output_refs)

If one task exceeds the cap, fail early:

raise ValueError(
    f"Checkpoint transform task {task.task_id} requires at least {required_gb:.2f} GB, "
    f"but max checkpoint transform RAM is {limit_gb:.2f} GB."
)

The cap must be allowed to be smaller than total model size, but not smaller than the largest indivisible grouped task.

Intermediate Tensor Policy

Do not write intermediate tensors by default.

Within a task:

load raw tensors
run all applicable transform stages in memory
write final output shard
release tensors

Only introduce spill-to-disk later if a real model needs it and the failure mode is understood.

Cache Key

The prepared checkpoint hash should be derived from the plan, not only from loose top-level fields.

Include at least:

  • source model ref or resolved source path
  • source checkpoint fingerprint
  • target dtype
  • task transform IDs
  • task parameters
  • input keys
  • output keys
  • output file naming
  • expert-parallel parameters:
    • moe_prefill_flavour
    • moe_prefill_num_pipeline_stages
    • moe_prefill_num_parallelized_experts
    • moe_prefill_expert_parallel_chunk_size if it affects layout/output

This fixes the incomplete TODO-6 behavior where two expert_parallel layouts can collide in the same prepared directory.

Pipeline Responsibilities

CheckpointTransformPipeline.apply() should own:

  • source format validation
  • reading the original weight_map
  • building the plan
  • checking cache manifest
  • clearing stale output
  • invoking the memory-bounded executor
  • writing final model.safetensors.index.json
  • copying sidecars
  • writing manifest
  • touching sentinel

Transform classes should not independently write index, manifest, sidecars, or sentinel.

Manifest

Bump or extend the manifest to include:

  • manifest version
  • source path
  • target dtype
  • source file fingerprint
  • plan fingerprint
  • active transform IDs
  • transform parameters
  • final output files

The manifest should be strict enough that a changed packing layout, transform parameter, or source file invalidates the
prepared directory.

Migration Steps

  1. Add TensorRef, CheckpointTask, and planning helpers.
  2. Add a memory-bounded task executor.
  3. Implement dense dtype conversion as planned base shard tasks.
  4. Convert per-expert MoE stacking to layer-level grouped tasks.
  5. Convert GPT-OSS MXFP4 dequant/split to layer-level grouped tasks.
  6. Convert fused expert split to grouped tasks using canonical key mapping.
  7. Fold expert-parallel packing into the relevant grouped tasks instead of using separate combined subclasses.
  8. Move all finalization to CheckpointTransformPipeline.apply().
  9. Derive prepared checkpoint hash from the plan fingerprint.
  10. Remove or update the stale selector TODO once the new pipeline supports composable stages.

Validation

Use existing weight-free tests where possible. Add focused cases under existing test files rather than creating broad new
test files.

Minimum tests:

  • dense checkpoint still performs dtype conversion and writes a valid index
  • per-expert MoE stacking writes canonical final keys
  • GPT-OSS MXFP4 dequant/split writes canonical final keys
  • fused expert split handles Mixtral-style and GraniteMoE-style keys
  • expert_parallel with different P/E values produces different prepared hashes
  • one logical key can pass through multiple stages before final write
  • grouped task waits until all required keys are present
  • missing required grouped key fails before writing a partial prepared checkpoint
  • memory budget limits concurrent grouped tasks
  • one task above memory cap raises a clear error

Acceptance Criteria

  • No transform owns global finalization.
  • No intermediate checkpoint files are written for normal stack/dequant/split/pack flows.
  • Final output tensors are written once.
  • Final weight_map contains only valid final tensor keys and existing shard files.
  • Cache identity changes when transform layout or expert_parallel packing parameters change.
  • The pipeline can represent multiple transforms on one logical key without hardcoded combined subclasses.

read_weight_map() (checkpoint_utils.py):
  - Remove shard-scan fallback that opened every shard file just to
    reconstruct an index already available in model.safetensors.index.json.
  - Single-file model (exactly 1 shard, no index): open once and return.
  - Zero safetensors: FileNotFoundError with clear message.
  - Multiple shards, no index: FileNotFoundError identifying malformed
    checkpoint — callers no longer silently scan on broken inputs.

CheckpointTransformPipeline.apply() (base/checkpoint_transforms.py):
  - Drop silent .bin → safetensors rewrite which doubled I/O and disk
    usage with no user visibility.
  - Raise ValueError immediately when .bin files are present so callers
    know exactly what to fix.
  - Remove now-unused convert_bin_to_safetensors import.

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
…(TODO-6)

base/checkpoint_transforms.py:
  - Add detect_group_transform_id(config, weight_map, hash_params) -> str.
    Uses config.num_experts as the MoE gate and inspects weight_map key
    patterns to identify the checkpoint layout without opening any shard
    files.  Returns stable TRANSFORM_ID strings that will map 1:1 to the
    group transform classes introduced in the pipeline redesign.
  - Simplify _checkpoint_manifest(): remove original_source field (source_dir
    always equals src after Stage ①), add active_group field, bump version to 2.
  - Simplify _checkpoint_file_fingerprint(): drop label parameter.
  - Simplify _clear_stale_prepared_dir(): drop source_dir parameter.
  - Read weight_map once at the top of apply() so detection and transform
    selection share the same dict.

export.py:
  - Add _prepared_checkpoint_hash(model_ref, dtype, active_group_id,
    moe_flavour) -> 12-char sha256.  Different model flavours (dense vs MoE,
    decode vs expert_parallel, different quantizations) now hash to different
    prepared directories and never silently overwrite each other.
  - _prepare_checkpoint_for_weight_free_export() detects the active group
    transform upfront, computes the hash, and uses it in prepared_name instead
    of the plain dtype suffix.

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
…DO-5)

  - Pipeline passes weight_map to transform.apply() so transforms never
    re-read the index themselves.
  - MoEExpertStackingCheckpointTransform: replace Phase 1 ThreadPoolExecutor
    shard scan with O(N) dict iteration on the passed weight_map.
  - GptOssMxfp4ExpertDequantSplitCheckpointTransform: same.
  - MoEFusedExpertSplitCheckpointTransform: replace inline index re-read
    duplication (TODO-5) with read_weight_map() fallback.
  - GraniteMoeFusedExpertSplitCheckpointTransform: same pattern.
  All four transforms accept weight_map as an explicit Optional parameter
  and fall back to read_weight_map(src) only when called without it.

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
…n (TODO-1)

  detect_group_transform() returns the active layout transform class directly
  (not a string ID), eliminating the is_applicable() selector loop.

  Pipeline execute logic:
    transforms_to_run = [active_layout_transform, DtypeConversionCheckpointTransform]
    for each: apply(remaining_keys), collect result, shrink consumed set

  Each layout transform (MoEExpertStacking, GptOssMxfp4Dequant,
  MoEFusedExpertSplit) gains:
    + TRANSFORM_ID: stable cache hash identifier
    + get_consumed_keys(): declares which keys it owns
    - Phase 3 removed: base key dtype conversion deleted from layout transforms
    - sentinel.touch(), write_index(), copy_checkpoint_aux_files() removed
    - apply() now returns Dict[str, str] instead of bool

  DtypeConversionCheckpointTransform gains TRANSFORM_ID + get_consumed_keys()
  and always runs on remaining keys after any layout transform.

  Stage ⑤ (finalise): sidecar copy, write_index, manifest, sentinel now
  handled once in the pipeline after all transforms complete.

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
…roach

  Replaces MoEFusedExpertSplitCheckpointTransform and the now-deleted
  GraniteMoeFusedExpertSplitCheckpointTransform with one class:

  FusedExpertSplitCheckpointTransform:
    _get_key_remap(weight_map): detects architecture from index.json keys.
      input_linear.weight present → GraniteMoE remap
      otherwise → Mixtral fused (already canonical, no remap)
    build_canonical_maps(weight_map, remap) produces:
      canonical_index: {canonical_key → shard_file}     WHERE to find tensor
      key_translation: {canonical_key → actual_key}     WHAT to ask shard for
    Single pass — loads by actual key, writes by canonical output key.
    No shape reads — split dim determined from bias key presence in canonical_index.

  _checkpoint_transforms now has 4 entries; no architecture-specific subclasses.
  detect_group_transform() delegates pre-stacked detection to is_applicable().

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
  Each layout transform now declares resolve_onnx_key(onnx_key, index):
    MoEExpertStackingCheckpointTransform:   direct + .mlp.→.block_sparse_moe.
    FusedExpertSplitCheckpointTransform:    direct + .mlp.→.block_sparse_moe.
    GptOssMxfp4ExpertDequantSplit:          direct match only

  find_checkpoint_key() updated:
    1. Universal HF prefix rules (unchanged)
    2. active_transform.resolve_onnx_key() — explicit per-architecture
    3. Legacy MoE alias fallback (kept for old checkpoints)

  Hardcoded .mlp./.gate.weight/.router.weight rules removed from resolver.
  promote_initializers_and_build_spec() detects active_transform from
  qeff_model and passes it to find_checkpoint_key().

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
  Each layout transform now declares resolve_onnx_key(onnx_key, index):
    MoEExpertStackingCheckpointTransform:   direct + .mlp.→.block_sparse_moe.
    FusedExpertSplitCheckpointTransform:    direct + .mlp.→.block_sparse_moe.
    GptOssMxfp4ExpertDequantSplit:          direct match only

  find_checkpoint_key() updated:
    1. Universal HF prefix rules (unchanged)
    2. active_transform.resolve_onnx_key() — explicit per-architecture
    3. Legacy MoE alias fallback (kept for old checkpoints)

  Hardcoded .mlp./.gate.weight/.router.weight rules removed from resolver.
  promote_initializers_and_build_spec() detects active_transform from
  qeff_model and passes it to find_checkpoint_key().

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
  Bug 1: Old MoEFusedExpertSplitCheckpointTransform and
  GraniteMoeFusedExpertSplitCheckpointTransform class definitions were
  never removed after Stage ⑤ aliased them to FusedExpertSplitCheckpoint
  Transform.  The redefinitions overrode the aliases, restored the old
  bool return type, and broke the Stage ④ pipeline contract.  Deleted.

  Bug 2: FusedExpertSplitCheckpointTransform.get_consumed_keys() returned
  canonical keys (experts.gate_up_proj) but the pipeline's remaining
  computation filters against original weight_map keys (input_linear.weight
  for GraniteMoE).  Mismatch meant DtypeConversion would re-process expert
  keys.  Fixed to iterate original keys and map to canonical for matching.

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
  - find_checkpoint_key(): add lm_head.weight → wte.weight fallback for
    GPT-family models where lm_head is not stored in the checkpoint.
  - checkpoint_key_resolver: read active_group TRANSFORM_ID from prepared
    checkpoint manifest (.checkpoint_prepared.json) instead of re-running
    detect_group_transform() on the prepared weight_map (which has output
    keys, not the original expert keys).
  - GptOssMxfp4ExpertDequantExpertParallelCheckpointTransform: new transform
    for GptOss MXFP4 with expert_parallel prefill — dequant + repack
    [E,H,I] → [E/P,P,H,I] via pack_moe_weights_for_expert_parallel().
  - detect_group_transform(): use config.model_type == 'gpt_oss' to route
    GptOss (cleaner than _blocks key scan), with expert_parallel routing.
  - _load_prepared_tensors: scan shards when index.json is absent (needed
    for unit tests that call transforms directly without the pipeline).

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
Signed-off-by: Amar <amarshar@qti.qualcomm.com>
Signed-off-by: Amar <amarshar@qti.qualcomm.com>
@amarquic
amarquic force-pushed the updated_checkpoint_design branch from 4aacb94 to f4c3e22 Compare September 22, 2026 10:52
@quic-amitraj

Copy link
Copy Markdown
Contributor Author

CI-Ready

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
Signed-off-by: Amar <amarshar@qti.qualcomm.com>
1. _find_transform_by_id(): add expert-parallel transform IDs so
   promote_initializers_and_build_spec() can recover the active_transform
   from the manifest and apply resolve_onnx_key() (.mlp.→.block_sparse_moe.).
   - moe_expert_parallel_stacking_v1 → MoEExpertParallelStackingCheckpointTransform
   - gptoss_mxfp4_dequant_expert_parallel_v1 → GptOssMxfp4ExpertDequantExpertParallelCheckpointTransform

2. _prepared_checkpoint_hash(): include moe_prefill_num_pipeline_stages and
   moe_prefill_num_parallelized_experts so two expert_parallel exports with
   different P/E values produce different prepared directories.

3. flavours.py: restore expand_as for matched_idx; torch.full_like on
   int32_max_scalar was an accidental change — the original compiler-preferred
   workaround uses expand_as on a scalar to avoid ConstantOfShape(INT32_MAX).

Signed-off-by: Amar <amarshar@qti.qualcomm.com>
Signed-off-by: Amar <amarshar@qti.qualcomm.com>
@amarquic
amarquic force-pushed the updated_checkpoint_design branch from f4c3e22 to 5b685cf Compare September 22, 2026 19:38
@quic-rishinr

Copy link
Copy Markdown
Contributor

@quic-amitraj please add proper description

@quic-rishinr

Copy link
Copy Markdown
Contributor

CI-Ready

from QEfficient.transformers.moe.weights import _pack_expert_parallel_tensor # noqa: PLC0415

# Step 1: standard per-expert stacking → moe_weights.gate/up/down [E, H, I]
new_weight_map = super().apply(src, out, target_dtype=target_dtype, weight_map=weight_map, **kwargs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still writes stacked experts-layer-* shards and then reopens/overwrites them for expert-parallel packing. The requested shape was raw group -> stack/dequant/split -> pack -> final write inside
one task, with no normal intermediate checkpoint stage.


new_weight_map: Dict[str, str] = {}
consumed: set = set()
for transform in transforms_to_run:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still the selector/consumed-key model from the previous review. A raw key can only be owned by one transform, so multi-stage flows still have to be encoded as combined transform classes
instead of planned tasks with staged refs. Please move this to the planned task pipeline or stop claiming the pipeline TODO is addressed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qeff.weightfree WeightFree Onnx Export based on Dyanmo and Meta state

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants