Commit Graph
5 Commits
Author SHA1 Message Date
aszc-dev 3adb216763 chore(phase6,bench): record quantization tradeoff matrix
Phase 6 reference numbers for SD1.5 1x512x512 SPLIT_EINSUM, captured
against commit 0bbd8d8 on M2 Pro 32GB (macOS 26.1, coremltools 9.0,
numpy 1.26.4, torch 2.7.1, Python 3.12.11) — same toolchain as Phase 5
baseline ef2a18c-rebased 1e5791d.

Headline:
- size shrinks 1641 MB -> 822 / 617 / 412 MB (1/2, 1/2.7, 1/4)
- fwd-pass median drops 197 ms -> 187 / 183 / 180 ms (5-9% faster)
- noise_pred PSNR vs unquantized: 53.5 / 40.2 / 27.5 dB

The fwd-ms improvement is mostly weight-load bandwidth (smaller LUT
reads). PSNR is on the raw UNet output at a fixed seed; final-image
PSNR after 20 sampler steps is comfortably higher.
2026-05-25 01:31:30 +02:00
aszc-dev 0bbd8d8e0d feat(phase6): opt-in k-means weight palettization (quantize_nbits)
Phase 6 of the modernization plan: add weight palettization to the
Core ML converter as an opt-in knob, so the SD1.5 / SDXL UNet can
ship at 1/2, 1/2.7 or 1/4 of its current size with ANE-friendly
inference.

CoreMLConverter (and the LCM converter) gains a `quantize_nbits`
dropdown: `none` (default — identical to pre-Phase-6 behavior and
filenames, so existing cached .mlpackages still resolve) / `8` / `6` /
`4`. The value is encoded as `_q<bits>` after the attn suffix, so the
unquantized model and the three palettized variants coexist on disk
under distinct cache keys.

Implementation
- core/naming.compose_out_name: accepts `quantize_nbits`, validates
  against {none, 8, 6, 4}, appends `_q<bits>` (none = empty).
- converter.convert_unet: after ct.convert + before .save, runs
  coremltools.optimize.coreml.palettize_weights with
  OpPalettizerConfig(mode="kmeans", nbits=...) when the value is not
  "none". Adds a `Palettization took Xs` log line.
- converter.convert / nodes.CoreMLConverter.convert: pipe the new arg
  through; the ComfyUI node exposes it as a dropdown with default
  "none" so existing workflows are unchanged at load time.
- bench/scripts/convert_sd15.py: QUANT_NBITS env knob; uses the
  pure compose_out_name (replaces the inline string formatter).

Test infra
- tests/unit/test_characterization_out_name.py: 6 new tests pinning
  the `_q<bits>` suffix contract, the "none" passthrough (backward
  compat), the cn + lora + quant combination, and the invalid-value
  ValueError. Total Tier 0 now at 94.
- Makefile gains `bench-quant` (runs the matrix script) and
  `convert-quant` (converts q8, q6, q4 sequentially).
- bench/scripts/quant_matrix.py (new): loads each variant, runs
  REPEATS forward passes with a fixed seed, then computes the
  noise_pred PSNR of each quantized variant against the unquantized
  baseline. Writes bench/results/quant_matrix_<sha>.{json,md}.

README
- New "Quantization (Phase 6, opt-in)" section: tradeoff table
  measured on M2 Pro SD1.5 1x512x512 SPLIT_EINSUM (sizes 1641/822/
  617/412 MB; fwd 197/187/183/180 ms; PSNR 53.5 / 40.2 / 27.5 dB),
  plus per-chip/RAM recommendations.

Default-path safety
- "none" produces the same out_name as Phase 5 -> existing
  v1-5-pruned-emaonly_1x512x512_se_unet.mlmodelc is still picked up
  unchanged; the m2 golden image test continues to anchor.
2026-05-25 01:30:29 +02:00
aszc-dev 2b649e6606 chore(phase5,bench): record bumped-toolchain environment and results
Phase 5 reference numbers, captured against commit 1e5791d on macOS
26.1 with the bumped toolchain (torch 2.7.1, coremltools 9.0, numpy
1.26.4, Python 3.12.11).

- bench/env/baseline-1e5791d.txt: full uv-pip freeze + ComfyUI sha +
  macOS + resolved ml-stable-diffusion git metadata.
- bench/env/pytest-unit-1e5791d.txt: pytest -m unit 88/88 passing
  (Tier-0 purity gate confirms no comfy/coreml leak).
- bench/results/1e5791d.{json,md}: SD1.5 1x512x512 SPLIT_EINSUM UNet
  forward latency on the Apple Neural Engine and CPU+GPU. Held within
  noise of the Phase 1 baseline (ef2a18c.json) — bump is
  performance-neutral.
2026-05-24 16:37:26 +02:00
aszc-dev cf6d7c6855 chore(phase1,bench): record baseline environment and results
Phase 1 reference numbers, captured against commit ef2a18c on macOS 26.1
with the pinned toolchain (torch 2.0.1, coremltools 8.2, numpy 1.23.5,
python_coreml_stable_diffusion@e5d960c4).

- bench/env/baseline-ef2a18c.txt: full pip freeze + ComfyUI sha + macOS +
  resolved ml-stable-diffusion git metadata.
- bench/env/pytest-unit-ef2a18c.txt: pytest tests/unit (test_chunks +
  test_controlnet) 20/20 passing.
- bench/results/ef2a18c.{json,md}: SD1.5 1x512x512 SPLIT_EINSUM UNet
  forward latency on the Apple Neural Engine and CPU+GPU. NE median 197 ms
  / GPU median 270 ms; a second run reproduced both within 0.3% (noise).
- bench/results/smoke/ef2a18c/: end-to-end Core ML image (E2E-1.5-CoreML
  workflow, seed=42) saved by smoke_image.py. The MPS reference branch of
  the original workflow is omitted because torch 2.0.1's MPS backend on
  macOS 26.1 trips a BFloat16 conversion error in VAEDecode and an
  mps.add element-type mismatch in KSampler — both go away with newer
  torch and are tracked for the Phase 5 toolchain bump. The server was
  started with --cpu-vae to route the VAE through CPU; this is a runtime
  flag, not a pin change.
2026-05-22 15:08:31 +02:00
aszc-dev ef2a18cff3 chore(phase1): pin baseline toolchain and add bench harness scaffold
Phase 1 of the modernization plan: freeze the currently-working environment
so later refactors have a measured reference point.

- Pin python-coreml-stable-diffusion to commit e5d960c4 (the one already
  installed in the maintainer's apple_env), plus torch==2.0.1, coremltools==8.2
  and numpy<1.25 to match the only env that loads ComfyUI successfully
  (Comfy's checkpoint-safe-loading branch in utils.py is gated on torch>=2.4,
  so newer torch + numpy 1.23 breaks at import).
- Mirror the same pins in requirements.txt and commit uv.lock for
  reproducible installs.
- Add requires-comfyui pinning ComfyUI to ab541335 (the validated commit).
- Fix tests/unit/test_chunks.py fixture: get_model_config() now takes a
  ModelVersion argument; pass ModelVersion.SD15 (the previously-broken test
  was the only Phase 1 production-code change required).
- Add the Phase 1 baseline harness: bench/run.py (direct Core ML UNet
  latency, deterministic), bench/scripts/convert_sd15.py (one-command
  conversion bypassing the node graph), bench/scripts/smoke_image.py (POSTs
  the existing e2e workflow to a local ComfyUI server and saves the Core ML
  image), bench/env/capture.sh (env snapshot), bench/prompts.json (fixed
  prompt set).
- Ignore apple_env/, comfy_env/, and bench/scripts/*.log.

Tests: 20/20 unit pass (test_chunks + test_controlnet).
2026-05-22 15:06:24 +02:00