Skip to content

Reuse compatible GGUF weights as ONNX external data - #573

Open
justinchuby wants to merge 4 commits into
justinchuby-gguf-registry-foundationfrom
justinchuby-reuse-gguf-weights
Open

Reuse compatible GGUF weights as ONNX external data#573
justinchuby wants to merge 4 commits into
justinchuby-gguf-registry-foundationfrom
justinchuby-reuse-gguf-weights

Conversation

@justinchuby

@justinchuby justinchuby commented Aug 23, 2026

Copy link
Copy Markdown
Member

Summary

Stacked on #571 (justinchuby-gguf-registry-foundation). Adds an explicit opt-in path that publishes ONNX beside the original GGUF without writing a second full copy of byte-compatible weights.

mobius build-gguf output/model.gguf --output output/ --reuse-gguf-weights
package = build_from_gguf("output/model.gguf", reuse_gguf_weights=True)
package.save("output/")

Storage and transform behavior

  • Unchanged F32/F16 tensors and consumer-compatible native IQ4_NL, IQ4_XS, IQ3_S, IQ3_XXS, IQ2_XXS, IQ2_XS, IQ2_S, IQ1_S, IQ1_M, and MXFP4 tensors point at exact GGUF location + offset + length ranges.
  • Float transpose, norm offset, Llama Q/K row permutation, and Mamba A_log/shape transforms keep the source bytes and run as ONNX graph operations. Opaque packed UINT8 is never generically transposed.
  • Repacked, requantized, dequantized, synthesized, or otherwise materialized large tensors are written exactly once to model.onnx.data.
  • Disabling constant folding preserves the on-disk reuse but transformed weights may still allocate runtime buffers and add startup/execution cost.

Persistence and verification

A persistent same-directory advisory lock serializes writers, recovery, and shared verification. Mixed saving stages and fsyncs the sidecar, model, and manifest, validates the complete staged package, then installs it through an atomically published durable transaction journal with hard-linked rollback backups. The journal records replacing/committed state so crashes cannot produce mixed rollback or leak full backup copies. Interrupted reruns recover before save/verification; failed reruns restore prior artifacts; obsolete sidecars are removed transactionally.

Recovery deletes only staged and backup paths owned by a structurally and path-validated journal; generated-looking filenames are never treated as proof of ownership. Lock, journal, staged, backup, model, manifest, and sidecar paths reject symlinks and non-regular artifacts. Lock acquisition validates directory-entry/opened inode identity; journal files are created through exclusive no-follow temporary files and atomic replacement.

gguf-reuse.json pins source location, size, SHA-256, source tensor/qtype/range, initializer dtype/length, source/final shapes, transform name, and transform parameters. Verification enumerates every ONNX external initializer: each must be either an exact manifest-pinned GGUF range or a non-overlapping range in the one permitted sidecar. Sidecar ranges must exactly equal the byte count implied by concrete non-negative shape and supported dtype. Verification rejects unmanifested/unsafe locations, wrong dtype/qtype/shape/ranges, mixed reused/converted claims, and mutated transform wiring/constants/permutations.

Scope and runtime requirements

This PR supports one flat text-model package. The real little-endian GGUF must already be in the output directory. It rejects nested/non-flat packaging, mmproj/MTP packages, symlinks, unsafe hardlinks, generated-name collisions, changed source identity, safetensors output, and sidecar sharding rather than copying or linking the GGUF.

Use direct ONNX Runtime with graph optimization disabled:

options = ort.SessionOptions()
options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_DISABLE_ALL

--reuse-gguf-weights --runtime ort-genai is rejected because the current genai_config.json schema has no supported setting that requires disabled constant folding.

Validation

  • 214 affected GGUF builder, ModelPackage, runtime-package, CLI, API, and option-parity tests pass.
  • Synthetic mixed GGUF/sidecar execution matches the ordinary converted package numerically on ORT CPU with optimizations disabled.
  • Tests cover writer/verifier ownership, committed and interrupted crash recovery, atomic journal publication, unsafe links/artifacts, source collisions, preservation of generated-looking source/user files, complete external enumeration, exact sidecar nbytes, qtype/dtype/range and transform mutations, source identity, hardlink capability, stale-sidecar removal, and exception rollback.
  • lintrunner f --output oneline --all-files and lintrunner -a pass locally.

Waiver

No multi-GB public GGUF was downloaded. Real-weight validation is deferred to avoid a large network/storage dependency; synthetic files use the real GGUF writer/reader, exact offsets, native block routes, mixed persistence, reload, and ORT execution.

Add an explicit build-gguf opt-in that points compatible ONNX initializers at exact tensor ranges in the original GGUF while externalizing converted weights to a separate sidecar. Pin and verify source provenance, enforce safe flat packaging, and preserve mixed external references during save.

Document the initial consumer and layout limitations, including deferred graph-expressible transforms and ORT optimization requirements, and cover mixed save/reload, exact ranges, unsafe paths, identity changes, and CPU inference.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Comment thread src/mobius/integrations/gguf/_reuse.py Fixed
Comment thread src/mobius/integrations/gguf/_reuse.py Fixed
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing 184176f5cc663c

Model Sub-model Changes Status

No architecture changes detected.


Legend: ⚪ No change · 🔵 Minor (attrs/inits) · 🟡 Moderate (nodes added/removed) · 🔴 Major (interface changed)

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing 184176f5cc663c

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 68 68 +0.0%
falcon model_size_bytes 364 KB 364 KB +0.0%
falcon num_nodes 66 66 +0.0%
gemma2 model_size_bytes 428 KB 428 KB +0.0%
gemma2 num_nodes 105 105 +0.0%
gpt2 model_size_bytes 388 KB 388 KB +0.0%
gpt2 num_nodes 54 54 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 60 60 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 56 56 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 94 94 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 58 58 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 54 54 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 60 60 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 56 56 +0.0%
qwen3_5_moe (hybrid-text-generation) model_size_bytes 506 KB 506 KB +0.0%
qwen3_5_moe (hybrid-text-generation) num_nodes 264 264 +0.0%
qwen3_5_text (hybrid-text-generation) model_size_bytes 458 KB 458 KB +0.0%
qwen3_5_text (hybrid-text-generation) num_nodes 126 126 +0.0%
qwen3_5_vl (hybrid-qwen-vl) model_size_bytes 977 KB 977 KB +0.0%
qwen3_5_vl (hybrid-qwen-vl) num_nodes 428 428 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 176 176 +0.0%
whisper (speech-to-text) model_size_bytes 1008 KB 1008 KB +0.0%
whisper (speech-to-text) num_nodes 128 128 +0.0%

No performance regressions.

justinchuby and others added 3 commits August 23, 2026 17:22
Reject ORT GenAI packaging when constant folding cannot be disabled, verify every external initializer and graph-level transform against the source manifest, and retain graph-expressible float transforms over GGUF-backed bytes.

Stage, fsync, validate, and transactionally install the model, sidecar, and manifest with durable rollback journals, crash recovery, confined journal paths, obsolete artifact removal, and explicit filesystem capability checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Protect mixed-package recovery and replacement with a persistent advisory lock, publish transaction state atomically, and reject unsafe generated artifacts without following links. Validate converted sidecar references against their exact dtype-and-shape byte size and cover concurrent ownership, crash recovery, symlink mutation, and truncated or oversized ranges.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e99f9fcb-697e-4853-b34c-b854c3995535
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Remove filename-inferred stale staging cleanup so recovery deletes only artifacts named by a structurally validated transaction journal. Cover a source GGUF and unrelated user file whose names resemble generated staging files.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e99f9fcb-697e-4853-b34c-b854c3995535
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants