Skip to content

Add direct quantized layer package workflow - #901

Merged
i386 merged 5 commits into
mainfrom
jd/skippy-quantize-workflows
Jun 23, 2026
Merged

Add direct quantized layer package workflow#901
i386 merged 5 commits into
mainfrom
jd/skippy-quantize-workflows

Conversation

@i386

@i386 i386 commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add direct BF16/FP16 GGUF -> quantized Skippy layer package flow to skippy-quantize
  • require custom quant profiles to be expressed via tensor recipes, not baked --quant aliases
  • forward tensor recipe files and metadata overrides into package quant hooks, including GLM-DSA indexer metadata

Validation

  • cargo fmt -p skippy-quantize
  • cargo test -p skippy-quantize
  • cargo clippy -p skippy-quantize --all-targets -- -D warnings

Lab proof

  • GLM-5.2 Q2_K with MTP/indexer tensors held at Q8 is currently being packaged from the local BF16 GGUF artifact using this flow.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added quantize-layer-package CLI subcommand for generating and quantizing layer packages from BF16 source files.
    • Implemented byte-balanced GGUF tensor splitting for improved distribution across splits.
    • Added GLM-DSA attention indexer metadata support.
  • Documentation

    • Updated guidance: custom quantization profiles now belong in artifact naming via --target-prefix / --output-basename, not in the --quant flag.
    • Added "BF16 to layer package" recipes subsection with workflow examples.
  • Bug Fixes

    • Artifact metadata now calculated from post-quantization files rather than pre-quantization values.
    • Removed support for recipe-style quant labels; users must specify base quant and custom tensor policies via --tensor-type-file.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR removes custom QuantSpec recipe label support (e.g., UD-Q3_K_S, Q4_K_XL) in favor of base quant types plus --tensor-type-file, adds a new quantize-layer-package CLI subcommand that orchestrates a bash hook script with skippy-model-package, changes GGUF tensor splitting from count-based to byte-balanced boundaries, adds GLM-DSA indexer metadata generation, and fixes artifact hook ordering in write_package_artifact.

Changes

skippy-quantize and skippy-model-package pipeline

Layer / File(s) Summary
QuantSpec recipe label removal and error messaging
crates/skippy-quantize/src/types.rs, crates/skippy-quantize/src/type_catalog.rs, crates/skippy-quantize/src/direct_quantize.rs, crates/skippy-quantize/tests/direct_quantize_cli.rs
QuantSpec.recipe_label field and FromStr recipe-name recognition are removed; parsing now accepts only base QuantType. unsupported_quant_type_error gains an MTPQ8 branch. QuantCatalog drops known_recipe_labels. All affected unit and CLI tests updated to expect parse failures for recipe-format strings and updated error messages.
GLM-DSA indexer metadata generation
crates/skippy-quantize/src/gguf_template.rs
metadata_from_hf_config_with_options calls a new push_glm_dsa_indexer_metadata step that emits three glm-dsa.attention.indexer.* GGUF key/value pairs when arch == "glm-dsa", backed by push_required_first_u32; covered by a new unit test.
Byte-balanced GGUF tensor splits and offset extraction
crates/skippy-quantize/src/gguf_writer.rs, crates/skippy-quantize/src/gguf_writer_tests.rs
select_split_tensors switches from proportional tensor-count boundaries to byte_balanced_split_boundaries. assign_gguf_offsets is extracted as a dedicated helper called earlier in prepare_raw_safetensors_gguf. Tests assert absolute_offset == data_start and verify byte-balanced split output with uneven tensor sizes.
quantize-layer-package CLI subcommand
crates/skippy-quantize/src/main.rs, crates/skippy-quantize/src/native_quantize.rs, crates/skippy-quantize/README.md
Adds QuantizeLayerPackageArgs, Command::QuantizeLayerPackage, and quantize_layer_package implementing manifest lock, bash hook-script generation, skippy-model-package write-package invocation, and preflight --verify-sha256. Helpers cover bash quoting and optional arg forwarding. Native-quantize tests cover --tensor-type-file forwarding and append ordering. README updated with BF16-to-layer-package recipe and revised Recipes guidance.
write_package_artifact hook ordering fix
crates/skippy-model-package/src/main.rs
run_artifact_hook is called before re-opening the artifact; tensor_count, tensor_bytes, sha256, and artifact_bytes are derived from post-hook artifact contents on disk; relative_path is computed earlier for both the hook call and PackageArtifact.path.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(70, 130, 180, 0.5)
        Note over CLI,preflight: quantize-layer-package flow
    end
    participant CLI as quantize-layer-package
    participant quantize_layer_package
    participant HookScript as quantize-package-artifact.sh
    participant skippy_model_package as skippy-model-package write-package
    participant preflight

    CLI->>quantize_layer_package: QuantizeLayerPackageArgs (validate, lock manifest)
    quantize_layer_package->>HookScript: write bash hook script to quant scratch dir
    quantize_layer_package->>skippy_model_package: write-package --post-artifact-command hook
    loop per artifact
        skippy_model_package->>HookScript: invoke with ARTIFACT_PATH env
        HookScript->>HookScript: skippy-quantize quantize (base quant + --tensor-type-file)
        HookScript-->>skippy_model_package: move quantized result to artifact location
    end
    skippy_model_package-->>quantize_layer_package: package written
    quantize_layer_package->>preflight: --verify-sha256 [--stages]
    preflight-->>quantize_layer_package: verification result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Mesh-LLM/mesh-llm#898: Initial skippy-quantize implementation that added the recipe-label support in type_catalog.rs and types.rs that this PR removes.

Suggested reviewers

  • ndizazzo
  • michaelneale
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add direct quantized layer package workflow' directly and clearly summarizes the main change: introducing a new workflow for converting BF16/FP16 GGUF files into quantized Skippy layer packages, which aligns with the PR's primary objective and the substantial additions to main.rs and supporting files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jd/skippy-quantize-workflows

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/skippy-quantize/src/main.rs`:
- Around line 679-717: The quantize_layer_package function removes the
manifest.target directory without validating that it is distinct from the source
and package-dir paths, which could cause accidental deletion of source data or
the newly-written package. Add ensure! checks early in the function (alongside
the existing validation checks) to verify that manifest.target does not equal or
overlap with args.package_dir and the source path from args.init, then let the
cleanup proceed only if these paths are confirmed to be disjoint. Use
descriptive error messages that reference the specific paths to help users
understand path conflicts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 32cee611-9569-4801-bbe2-c2cc361b97c4

📥 Commits

Reviewing files that changed from the base of the PR and between d389841 and 7d9d3c3.

📒 Files selected for processing (11)
  • crates/skippy-model-package/src/main.rs
  • crates/skippy-quantize/README.md
  • crates/skippy-quantize/src/direct_quantize.rs
  • crates/skippy-quantize/src/gguf_template.rs
  • crates/skippy-quantize/src/gguf_writer.rs
  • crates/skippy-quantize/src/gguf_writer_tests.rs
  • crates/skippy-quantize/src/main.rs
  • crates/skippy-quantize/src/native_quantize.rs
  • crates/skippy-quantize/src/type_catalog.rs
  • crates/skippy-quantize/src/types.rs
  • crates/skippy-quantize/tests/direct_quantize_cli.rs

Comment on lines +679 to +717
fn quantize_layer_package(args: QuantizeLayerPackageArgs) -> Result<()> {
ensure!(
args.init.window_size == 1,
"quantize-layer-package currently requires --window-size 1"
);
ensure!(
!args.runner.dry_run,
"quantize-layer-package does not support --dry-run; use quant-job --preflight-only first"
);
ensure!(
!args.runner.print_only,
"quantize-layer-package does not support --print-only; use quant-job --preflight-only first"
);
ensure!(
args.skippy_model_package_bin.is_file(),
"missing skippy-model-package binary {}; build it with `cargo build --release --locked -p skippy-model-package` or pass --skippy-model-package-bin",
args.skippy_model_package_bin.display()
);
if args.package_dir.exists() {
ensure!(
args.replace_package,
"package dir already exists: {}; pass --replace-package to overwrite it",
args.package_dir.display()
);
fs::remove_dir_all(&args.package_dir)
.with_context(|| format!("remove package dir {}", args.package_dir.display()))?;
}

let manifest = quant_manifest_from_args(&args.init)?;
let manifest_path = args.init.manifest.clone();
let runner = prepare_quant_runner(args.runner.clone())?;
with_manifest_lock(&manifest_path, || {
ensure_manifest(&manifest_path, &manifest)?;
let hook = write_layer_package_quant_hook(&args, &runner)?;
write_and_preflight_layer_package(&args, &manifest, &hook)?;
if !args.keep_quant {
remove_dir_if_exists(&manifest.target)?;
print_path_event("🧹", "Cleaned quant scratch", &manifest.target);
}

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Guard quant scratch cleanup from deleting source/package paths.

Line 714 removes manifest.target unconditionally (unless --keep-quant), but there is no guard that --target is disjoint from --source and --package-dir. A path overlap can wipe BF16 source data or the just-written package.

🛠️ Suggested fix
 fn quantize_layer_package(args: QuantizeLayerPackageArgs) -> Result<()> {
+    ensure!(
+        args.init.target != args.init.source && !args.init.source.starts_with(&args.init.target),
+        "--target cannot equal or contain --source; quant scratch cleanup removes --target"
+    );
+    ensure!(
+        args.init.target != args.package_dir && !args.package_dir.starts_with(&args.init.target),
+        "--target cannot equal or contain --package-dir; quant scratch cleanup removes --target"
+    );
     ensure!(
         args.init.window_size == 1,
         "quantize-layer-package currently requires --window-size 1"
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/skippy-quantize/src/main.rs` around lines 679 - 717, The
quantize_layer_package function removes the manifest.target directory without
validating that it is distinct from the source and package-dir paths, which
could cause accidental deletion of source data or the newly-written package. Add
ensure! checks early in the function (alongside the existing validation checks)
to verify that manifest.target does not equal or overlap with args.package_dir
and the source path from args.init, then let the cleanup proceed only if these
paths are confirmed to be disjoint. Use descriptive error messages that
reference the specific paths to help users understand path conflicts.

@i386
i386 merged commit ac010d5 into main Jun 23, 2026
22 checks passed
@i386
i386 deleted the jd/skippy-quantize-workflows branch June 23, 2026 22:10
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.

1 participant