## [1.2.1] — 2026-08-20
Browse files# Changelog
All notable changes to the AutoRound + ASHQ1 suite are documented in this file.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
---
## [1.2.1] — 2026-08-20
### Fixed
- **Upgrade queue now drains completely.** The greedy scheduler stopped at the first
candidate exceeding the remaining budget, abandoning every smaller move still
queued behind it. Because `current_size` grows monotonically, a rejected group
never fits later, so the oversized candidate is skipped and the queue keeps
draining. Measured on a 9B `qwen35` AutoRound int4 source: `Quality` recovered
214 MiB (5 939 → ~6 067 MiB) by upgrading `output.weight` to `Q5_K`, and `Compact`
reached 33.06% of the BF16 footprint against a 33% target.
- **Tier ratio in the final summary.** The summary table printed
`bf16_mib * ALL_RATIOS[tier]`, showing `Quality` at 39% (6 665 MiB) on int4 lineage
while the run had correctly targeted 36% (6 153 MiB). The summary now routes
through `resolve_ratio()` like the execution loop.
### Removed
- Dead code left by the 1.2.0 merge: the unused `resolve_tier_ratio()` helper and a
duplicate `INT4_TIER_RATIOS` definition.
### Verified
- Four-tier batch on a 17 091 MiB BF16 source: `Nano` 21.08%, `Mini` 27.01%,
`Compact` 32.95%, `Quality` 34.75% (pre-patch measurements).
- Overhead self-calibration converged to ×1.0000 after a single ×1.0016 correction;
`META_OVERHEAD_MIB=12` matches the +10/+11 MiB observed on disk.
- `-Quality-36pc.gguf` naming is emitted and re-detected correctly across runs.
|
@@ -966,7 +966,8 @@ def optimal_classify(importance_table:dict,tied_groups:list,model:dict,target_si
|
|
| 966 |
if assignments[group_registry[item.group_id][0][0]]!=item.from_tier:
|
| 967 |
continue
|
| 968 |
if item.size_delta>0 and current_size+item.size_delta>effective_target:
|
| 969 |
-
|
|
|
|
| 970 |
for n in group_registry[item.group_id][0]:
|
| 971 |
assignments[n]=item.target_tier
|
| 972 |
current_size+=item.size_delta
|
|
@@ -1589,7 +1590,7 @@ def tiers_main(args_list=None):
|
|
| 1589 |
print(f"{'='*60}")
|
| 1590 |
mode="quantized" if args.run else "dry-run"
|
| 1591 |
for tier,success in results.items():
|
| 1592 |
-
target=bf16_mib*
|
| 1593 |
status="✓ Done" if success else "✗ Failed"
|
| 1594 |
print(f" {tier_label(tier):<12}{target:>7.0f} MiB {status} ({mode})")
|
| 1595 |
print()
|
|
|
|
| 966 |
if assignments[group_registry[item.group_id][0][0]]!=item.from_tier:
|
| 967 |
continue
|
| 968 |
if item.size_delta>0 and current_size+item.size_delta>effective_target:
|
| 969 |
+
# Skip the oversized move and keep draining: current_size only grows, so this group never fits later
|
| 970 |
+
continue
|
| 971 |
for n in group_registry[item.group_id][0]:
|
| 972 |
assignments[n]=item.target_tier
|
| 973 |
current_size+=item.size_delta
|
|
|
|
| 1590 |
print(f"{'='*60}")
|
| 1591 |
mode="quantized" if args.run else "dry-run"
|
| 1592 |
for tier,success in results.items():
|
| 1593 |
+
target=bf16_mib*resolve_ratio(tier,int4)
|
| 1594 |
status="✓ Done" if success else "✗ Failed"
|
| 1595 |
print(f" {tier_label(tier):<12}{target:>7.0f} MiB {status} ({mode})")
|
| 1596 |
print()
|