Soulfate24 commited on
Commit
220afa1
·
verified ·
1 Parent(s): 4ba2e75

## [1.2.0] — 2026-08-20

Browse files

# Changelog

All notable changes to the AutoRound + ASHQ1 Suite are documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---

## [1.2.0] — 2026-08-20

Supersedes the unreleased 1.1.0 and folds it in. Validated on a 9B `qwen35` dense
model with SSM blocks, W4G128 AutoRound lineage, 17091 MiB BF16 source, 427 tensors,
129 tied groups, 249 imatrix entries over 696 chunks.

### Changed

- **`Compact` tier raised from 30% to 33% of the source BF16 footprint.**
Measured output: 5632 MiB against a 5640 MiB target, a 32.95% effective ratio.
The added budget lifts attention and FFN projections to the `Q5_K` lineage cap
instead of leaving them at `IQ4_XS` and `IQ3_S`.

- **`Quality` tier retargets to 36% on AutoRound int4 lineage.**
At 39% the scheduler exhausted its upgrade queue against `INT4_LINEAGE_CAP` and
left 364 MiB unspent, shipping 36.87%. The new target matches delivered size, so
filenames and metadata state the real ratio. Non-int4 lineages keep 39%.

- Tier ladder is now a clean 3% modulo: `Nano` 21%, `Mini` 27%, `Compact` 33%,
`Quality` 36% on int4 and 39% elsewhere, `Fidelity` 48%.

### Added

- `INT4_TIER_RATIOS` table with `resolve_ratio(tier,int4)` and `resolve_pct(tier,model)`
in `ASHQ1.py`, giving per-lineage tier budgets a single resolution point.
- Output filenames derive their percentage from the resolved ratio across `ASHQ1.py`
and the batch orchestrator, so an int4 `Quality` build is written as
`-Quality-36pc.gguf` and detected as such on resume.
- Tier size table printed at startup reflects the resolved per-lineage targets.
- Cap saturation rationale documented in `CHARTER.md` section 3, `README.md`,
and `USAGE.md`.

### Notes

- `free-embd` stays disabled across all tiers on this model: `token_embd` weighs
1031 MiB, which is 18.3% of the `Compact` target and exceeds the 15% threshold.
- Four-tier batch quantization completed in 14m58s; `Nano` is the slowest pass at
5m07s due to low-bit IQ search cost.
- `did not find weights for token_embd.weight` from llama.cpp is benign on tied
embeddings and does not affect the produced files.

Files changed (5) hide show
  1. 02_BF16-GGUF-to-ASHQ1.py +3 -3
  2. ASHQ1.py +26 -6
  3. CHARTER.md +2 -1
  4. README.md +3 -1
  5. USAGE.md +1 -1
02_BF16-GGUF-to-ASHQ1.py CHANGED
@@ -9,7 +9,7 @@ The COMPLETE model (including MTP head) is preferred over the no-mtp trunk:
9
  ASHQ1 keeps the nextn layer at Q8_0 (Q6_K on int4 lineage) and excludes it from the size budget.
10
  Final naming: model-AutoRound-ASHQ1-Compact-33pc.gguf (AutoRound lineage detected
11
  via step 00 sidecar), model-ASHQ1-…-NNpc.gguf otherwise; mmproj-ASHQ1-Balanced-NNpc.gguf
12
- (pct relative to source mmproj).
13
  Lineage override: ASHQ1_LINEAGE=autoround|plain.
14
  """
15
  import os,re,sys,subprocess
@@ -17,7 +17,7 @@ import os,re,sys,subprocess
17
  SCRIPT_DIR=os.path.dirname(os.path.abspath(__file__))
18
  sys.path.insert(0,SCRIPT_DIR)
19
  sys.path.insert(0,os.path.join(SCRIPT_DIR,"llama-cpp","gguf-py"))
20
- from ASHQ1 import ALL_RATIOS,int4_lineage_of,lineage_tag,tier_label
21
 
22
  MAIN_TIERS=["mini","compact","quality","fidelity"]
23
  # Longest running and least used: executed last
@@ -79,7 +79,7 @@ def process_model(base_dir,ashq1_script,imatrix,model_path,tiers_list):
79
  print(f"{'='*60}")
80
  for tier in tiers_list:
81
  label=tier_label(tier)
82
- pct=round(ALL_RATIOS.get(tier.lower(),0)*100)
83
  new_name=f"{clean_base}-{tag}-{label}-{pct}pc.gguf"
84
  new_file=os.path.join(base_dir,new_name)
85
  if os.path.isfile(new_file):
 
9
  ASHQ1 keeps the nextn layer at Q8_0 (Q6_K on int4 lineage) and excludes it from the size budget.
10
  Final naming: model-AutoRound-ASHQ1-Compact-33pc.gguf (AutoRound lineage detected
11
  via step 00 sidecar), model-ASHQ1-…-NNpc.gguf otherwise; mmproj-ASHQ1-Balanced-NNpc.gguf
12
+ (pct relative to source mmproj). On int4 lineage Quality targets 36% instead of 39%.
13
  Lineage override: ASHQ1_LINEAGE=autoround|plain.
14
  """
15
  import os,re,sys,subprocess
 
17
  SCRIPT_DIR=os.path.dirname(os.path.abspath(__file__))
18
  sys.path.insert(0,SCRIPT_DIR)
19
  sys.path.insert(0,os.path.join(SCRIPT_DIR,"llama-cpp","gguf-py"))
20
+ from ASHQ1 import ALL_RATIOS,int4_lineage_of,lineage_tag,resolve_pct,tier_label
21
 
22
  MAIN_TIERS=["mini","compact","quality","fidelity"]
23
  # Longest running and least used: executed last
 
79
  print(f"{'='*60}")
80
  for tier in tiers_list:
81
  label=tier_label(tier)
82
+ pct=resolve_pct(tier,model_path)
83
  new_name=f"{clean_base}-{tag}-{label}-{pct}pc.gguf"
84
  new_file=os.path.join(base_dir,new_name)
85
  if os.path.isfile(new_file):
ASHQ1.py CHANGED
@@ -1350,7 +1350,7 @@ def run_main_cli(args_list=None)->int:
1350
  return 0
1351
  if not args.output:
1352
  base=clean_name(args.model)
1353
- pct=round(ALL_RATIOS.get(args.profile,0.39)*100)
1354
  args.output=f"{base}-{lineage_tag(args.model,args.lineage)}-{tier_label(args.profile)}-{pct}pc.gguf"
1355
  print(f"\n--- Running quantization: {args.output} ---")
1356
  success=run_quantization(flags,args.model,args.output)
@@ -1415,12 +1415,30 @@ TIER_RATIOS={
1415
  "fidelity":0.48,
1416
  }
1417
 
 
 
 
 
 
 
 
 
1418
  ALL_RATIOS=dict(TIER_RATIOS)
 
1419
  TIER_DISPLAY={"nano":"Nano"}
1420
 
1421
  def tier_label(tier:str)->str:
1422
  return TIER_DISPLAY.get(tier.lower(),tier.capitalize())
1423
 
 
 
 
 
 
 
 
 
 
1424
  def file_size_mib(path:str)->float:
1425
  return os.path.getsize(path)/1024/1024
1426
 
@@ -1471,19 +1489,20 @@ def gen_imatrix(model:str,data:str,output:str,chunks:int)->bool:
1471
  return False
1472
  return result.returncode==0
1473
 
1474
- def print_tier_table(bf16_mib:float,model_name:str):
1475
  print(f"\n Model: {model_name}")
1476
  print(f" BF16 source: {bf16_mib:.0f} MiB ({bf16_mib/1024:.2f} GB)\n")
1477
  print(f" {'Tier':<12}{'Ratio':>6}{'Target(MiB)':>14}{'Target(GB)':>12}")
1478
  print(f" {'-'*12}{'-'*6}{'-'*14}{'-'*12}")
1479
- for tier,ratio in ALL_RATIOS.items():
 
1480
  target=bf16_mib*ratio
1481
  print(f" {tier_label(tier):<12}{ratio*100:>5.0f}%{target:>13.0f}{target/1024:>11.2f}")
1482
  print()
1483
 
1484
  def run_tier(model:str,imatrix_paths:list,tier:str,target_mib:float,output_dir:str,run:bool,extra_args:list,lineage:str="auto")->bool:
1485
  name=clean_name(model)
1486
- pct=round(ALL_RATIOS.get(tier,0)*100)
1487
  output=os.path.join(output_dir,f"{name}-{lineage_tag(model,lineage)}-{tier_label(tier)}-{pct}pc.gguf")
1488
  cmd_args=[
1489
  "--model",model,
@@ -1531,7 +1550,7 @@ def tiers_main(args_list=None):
1531
  output_dir=args.output_dir or os.path.dirname(os.path.abspath(args.model))
1532
  os.makedirs(output_dir,exist_ok=True)
1533
  print("=== ASHQ1 Tier Runner ===")
1534
- print_tier_table(bf16_mib,model_name)
1535
  if args.show_sizes:return
1536
  imatrix_paths=list(args.imatrix)
1537
  if args.gen_imatrix:
@@ -1559,9 +1578,10 @@ def tiers_main(args_list=None):
1559
  if args.allow_q3_or_lower:extra_args.append("--allow-q3-or-lower")
1560
  extra_args.extend(["--imatrix-method",args.imatrix_method,"--lineage",args.lineage])
1561
  if args.verbose:extra_args.append("--verbose")
 
1562
  results={}
1563
  for tier in tiers:
1564
- target=bf16_mib*ALL_RATIOS[tier]
1565
  success=run_tier(args.model,imatrix_paths,tier,target,output_dir,args.run,extra_args,args.lineage)
1566
  results[tier]=success
1567
  print(f"\n{'='*60}")
 
1350
  return 0
1351
  if not args.output:
1352
  base=clean_name(args.model)
1353
+ pct=resolve_pct(args.profile,args.model)
1354
  args.output=f"{base}-{lineage_tag(args.model,args.lineage)}-{tier_label(args.profile)}-{pct}pc.gguf"
1355
  print(f"\n--- Running quantization: {args.output} ---")
1356
  success=run_quantization(flags,args.model,args.output)
 
1415
  "fidelity":0.48,
1416
  }
1417
 
1418
+ INT4_TIER_RATIOS={"quality":0.36}
1419
+
1420
+ def resolve_tier_ratio(tier,lineage):
1421
+ # int4 upgrades stall against INT4_LINEAGE_CAP; high tiers get a truthful target
1422
+ if lineage=="int4" and tier in INT4_TIER_RATIOS:
1423
+ return INT4_TIER_RATIOS[tier]
1424
+ return TIER_RATIOS[tier]
1425
+
1426
  ALL_RATIOS=dict(TIER_RATIOS)
1427
+ INT4_TIER_RATIOS={"quality":0.36}
1428
  TIER_DISPLAY={"nano":"Nano"}
1429
 
1430
  def tier_label(tier:str)->str:
1431
  return TIER_DISPLAY.get(tier.lower(),tier.capitalize())
1432
 
1433
+ def resolve_ratio(tier:str,int4:bool)->float:
1434
+ # int4 upgrades stall against INT4_LINEAGE_CAP: high tiers get a truthful target
1435
+ t=tier.lower()
1436
+ if int4 and t in INT4_TIER_RATIOS:return INT4_TIER_RATIOS[t]
1437
+ return ALL_RATIOS.get(t,0.0)
1438
+
1439
+ def resolve_pct(tier:str,model_path:str)->int:
1440
+ return round(resolve_ratio(tier,int4_lineage_of(model_path))*100)
1441
+
1442
  def file_size_mib(path:str)->float:
1443
  return os.path.getsize(path)/1024/1024
1444
 
 
1489
  return False
1490
  return result.returncode==0
1491
 
1492
+ def print_tier_table(bf16_mib:float,model_name:str,int4:bool=False):
1493
  print(f"\n Model: {model_name}")
1494
  print(f" BF16 source: {bf16_mib:.0f} MiB ({bf16_mib/1024:.2f} GB)\n")
1495
  print(f" {'Tier':<12}{'Ratio':>6}{'Target(MiB)':>14}{'Target(GB)':>12}")
1496
  print(f" {'-'*12}{'-'*6}{'-'*14}{'-'*12}")
1497
+ for tier in ALL_RATIOS:
1498
+ ratio=resolve_ratio(tier,int4)
1499
  target=bf16_mib*ratio
1500
  print(f" {tier_label(tier):<12}{ratio*100:>5.0f}%{target:>13.0f}{target/1024:>11.2f}")
1501
  print()
1502
 
1503
  def run_tier(model:str,imatrix_paths:list,tier:str,target_mib:float,output_dir:str,run:bool,extra_args:list,lineage:str="auto")->bool:
1504
  name=clean_name(model)
1505
+ pct=resolve_pct(tier,model)
1506
  output=os.path.join(output_dir,f"{name}-{lineage_tag(model,lineage)}-{tier_label(tier)}-{pct}pc.gguf")
1507
  cmd_args=[
1508
  "--model",model,
 
1550
  output_dir=args.output_dir or os.path.dirname(os.path.abspath(args.model))
1551
  os.makedirs(output_dir,exist_ok=True)
1552
  print("=== ASHQ1 Tier Runner ===")
1553
+ print_tier_table(bf16_mib,model_name,int4_lineage_of(args.model))
1554
  if args.show_sizes:return
1555
  imatrix_paths=list(args.imatrix)
1556
  if args.gen_imatrix:
 
1578
  if args.allow_q3_or_lower:extra_args.append("--allow-q3-or-lower")
1579
  extra_args.extend(["--imatrix-method",args.imatrix_method,"--lineage",args.lineage])
1580
  if args.verbose:extra_args.append("--verbose")
1581
+ int4=int4_lineage_of(args.model)
1582
  results={}
1583
  for tier in tiers:
1584
+ target=bf16_mib*resolve_ratio(tier,int4)
1585
  success=run_tier(args.model,imatrix_paths,tier,target,output_dir,args.run,extra_args,args.lineage)
1586
  results[tier]=success
1587
  print(f"\n{'='*60}")
CHARTER.md CHANGED
@@ -52,7 +52,8 @@ When tied layers are detected (such as shared input/output embeddings or symmetr
52
  When weights are derived from an AutoRound W4A16 source (recorded via `.provenance.json` sidecars):
53
  * **Information Saturation**: Because the underlying weights have been pre-conditioned for 4-bit representations, assigning container formats above `Q5_K` yields negligible signal recovery ($\Delta \mathcal{Q} \to 0$).
54
  * **Automated Capping**: The ASHQ1 optimizer caps attention and FFN blocks at `Q5_K`, attention gates at `Q6_K`, and MTP heads at `Q6_K`, while recurrent memory states hold `Q8_0`. The bit-budget freed by these ceilings flows to the imatrix-ranked tensors that convert it into measurable error reduction.
55
- * **Tier Pruning**: On AutoRound int4 lineage, generation of the 48% `Fidelity` tier is skipped by default, focusing compute resources on optimal `Quality` (39%), `Compact` (33%), `Mini` (27%), and `Nano` (21%) variants.
 
56
 
57
  ---
58
 
 
52
  When weights are derived from an AutoRound W4A16 source (recorded via `.provenance.json` sidecars):
53
  * **Information Saturation**: Because the underlying weights have been pre-conditioned for 4-bit representations, assigning container formats above `Q5_K` yields negligible signal recovery ($\Delta \mathcal{Q} \to 0$).
54
  * **Automated Capping**: The ASHQ1 optimizer caps attention and FFN blocks at `Q5_K`, attention gates at `Q6_K`, and MTP heads at `Q6_K`, while recurrent memory states hold `Q8_0`. The bit-budget freed by these ceilings flows to the imatrix-ranked tensors that convert it into measurable error reduction.
55
+ * **Tier Pruning**: On AutoRound int4 lineage, generation of the 48% `Fidelity` tier is skipped by default, focusing compute resources on optimal `Quality` (36%), `Compact` (33%), `Mini` (27%), and `Nano` (21%) variants.
56
+ * **Cap Saturation**: On AutoRound int4 lineage, `Compact` (33%) drives every attention and FFN projection to the `Q5_K` cap. Measured on a 9B `qwen35` source: `Compact` delivers 32.95% of the BF16 footprint with 8 MiB of slack, while `Quality` at a 39% target exhausts its upgrade queue and ships 36.87%. `Quality` therefore retargets to 36% on this lineage; other lineages keep 39%.
57
 
58
  ---
59
 
README.md CHANGED
@@ -68,7 +68,9 @@ All tiers maintain strict byte-budget percentages relative to the original unqua
68
  | **Quality** | **39%** | `Q5_K_M` | Near-lossless general deployment | Full `Q4_K`/`Q5_K` attention coverage |
69
  | **Fidelity** | **48%** | `Q6_K` | Maximum analytical precision (raw BF16 lineage) | High-precision `Q5_K`/`Q6_K`/`Q8_0` mix |
70
 
71
- *Note: Models originating from an AutoRound int4 lineage cap their weight allocations at the Quality tier (`Q5_K`/`Q4_K` mix), as theoretical information saturation is fully realized. Attention gates settle at `Q6_K` and recurrent states at `Q8_0` on that lineage, and every tensor missing from the imatrix keeps `IQ4_XS` or above.*
 
 
72
 
73
  ### 🎯 Recommended Minimum Tiers by Model Size
74
 
 
68
  | **Quality** | **39%** | `Q5_K_M` | Near-lossless general deployment | Full `Q4_K`/`Q5_K` attention coverage |
69
  | **Fidelity** | **48%** | `Q6_K` | Maximum analytical precision (raw BF16 lineage) | High-precision `Q5_K`/`Q6_K`/`Q8_0` mix |
70
 
71
+ *Note: Models originating from an AutoRound int4 lineage cap their weight allocations at `Q5_K`, as theoretical information saturation is fully realized. Attention gates settle at `Q6_K` and recurrent states at `Q8_0` on that lineage, and every tensor missing from the imatrix keeps `IQ4_XS` or above.*
72
+
73
+ > **Int4 lineage tier ladder**: `Compact` (33%) already drives every attention and FFN projection to the `Q5_K` cap. Budget beyond that point buys `token_embd` and `output` precision only, so `Quality` retargets to **36%** on this lineage and writes `-Quality-36pc.gguf`. `Fidelity` stays pruned.
74
 
75
  ### 🎯 Recommended Minimum Tiers by Model Size
76
 
USAGE.md CHANGED
@@ -94,7 +94,7 @@ Smaller parameter architectures require higher relative bit precision to prevent
94
 
95
  * **≥ 9B Models**: Select **Mini** (27% ratio) or higher. Large parameter capacity preserves semantic integrity at lower bit rates.
96
  * **~ 4B Models**: Select **Compact** (33% ratio) or higher. Optimal balance between memory footprint and dense layer preservation.
97
- * **~ 3B Models**: Select **Quality** (39% ratio) or higher. Higher baseline precision protects critical routing and attention projections.
98
  * **≤ 1B Models**: Select **Fidelity** (48% ratio) or higher. Compact architectures require maximum parameter density.
99
 
100
  ---
 
94
 
95
  * **≥ 9B Models**: Select **Mini** (27% ratio) or higher. Large parameter capacity preserves semantic integrity at lower bit rates.
96
  * **~ 4B Models**: Select **Compact** (33% ratio) or higher. Optimal balance between memory footprint and dense layer preservation.
97
+ * **~ 3B Models**: Select **Quality** (39% ratio, 36% on AutoRound int4 lineage) or higher. Higher baseline precision protects critical routing and attention projections.
98
  * **≤ 1B Models**: Select **Fidelity** (48% ratio) or higher. Compact architectures require maximum parameter density.
99
 
100
  ---