ssmforge 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ssmforge-0.2.0/src/ssmforge.egg-info → ssmforge-0.2.2}/PKG-INFO +224 -5
- {ssmforge-0.2.0 → ssmforge-0.2.2}/README.md +223 -4
- {ssmforge-0.2.0 → ssmforge-0.2.2}/pyproject.toml +1 -1
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/__init__.py +1 -1
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/__init__.py +8 -1
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/graph.py +374 -33
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/state_dict_scan.py +41 -1
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/cli.py +232 -14
- {ssmforge-0.2.0 → ssmforge-0.2.2/src/ssmforge.egg-info}/PKG-INFO +224 -5
- {ssmforge-0.2.0 → ssmforge-0.2.2}/LICENSE +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/MANIFEST.in +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/docs/DEPLOY.md +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/docs/INSTALL.md +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/docs/quickstart.md +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/setup.cfg +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/diff.py +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/markdown_render.py +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/report.py +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge/analyze/summary.py +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge.egg-info/SOURCES.txt +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge.egg-info/dependency_links.txt +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge.egg-info/entry_points.txt +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge.egg-info/requires.txt +0 -0
- {ssmforge-0.2.0 → ssmforge-0.2.2}/src/ssmforge.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ssmforge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Standalone HF architecture analyzer (`ssmforge arch`). Inspects any HuggingFace model and reports architectural quirks — attention biases, fused QKV/gate-up, tied embeddings, GQA, MQA, MoE, sliding window, LayerScale, soft-capping, partial RoPE, MLP type, norm type. Outputs structured JSON + human-readable summary.
|
|
5
5
|
Author: SSMForge Contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -82,6 +82,28 @@ visible *before* you spend the next hour finding out the hard way.
|
|
|
82
82
|
It does **not** modify the model. It does **not** run inference. It only
|
|
83
83
|
inspects.
|
|
84
84
|
|
|
85
|
+
### What's new in 0.2.2
|
|
86
|
+
|
|
87
|
+
| Fix | What was broken |
|
|
88
|
+
|-----|-----------------|
|
|
89
|
+
| `--output PATH` with bad parent dir | Previously got a generic `bash: Permission denied` (when redirecting) or a Python traceback (when using `--output`). Now pre-flight checks the parent directory, prints a clear hint pointing at writable locations like `./` and `~/`, then exits 1. |
|
|
90
|
+
|
|
91
|
+
Plus 6 new tests (162 total). Tiny release — main bug fix only.
|
|
92
|
+
|
|
93
|
+
### What's new in 0.2.1
|
|
94
|
+
|
|
95
|
+
| Feature | Why it matters |
|
|
96
|
+
|---------|----------------|
|
|
97
|
+
| `doctor --check-install` | Diagnoses "ssmforge: command not found" in one command. Prints `✓` when on PATH, `✗` + a copy-pasteable fix hint when not. Exits non-zero so you can use it in scripts. |
|
|
98
|
+
| One-time PATH warning | First invocation when `ssmforge` is off-PATH prints a hint to stderr pointing at `python -m ssmforge.cli`. Suppressed by `SSMFORGE_NO_PATH_WARN=1`. Skipped for `doctor` so its output stays clean. |
|
|
99
|
+
| `--graph --format {text,json,markdown}` | `--graph` now respects `--format`. Single + compare modes emit ASCII (text), structured JSON (for pipelines), or GitHub-flavored Markdown (for docs/Issues). |
|
|
100
|
+
| `--graph` ASCII cleanup | Box-drawing hierarchy fixed: single-rail `▼` flow + box `╭╮╰╯` panels for ATTENTION and MLP, `├─/└─` decision-tree style inside. |
|
|
101
|
+
| Qwen2 attention_bias fixed | `config.attention_bias=None` + zero bias tensors (Qwen2's vestigial biases) no longer reports `attention_bias=True`. Now requires either config explicit True OR non-zero bias values. |
|
|
102
|
+
| `--compare A A` is now valid | Was previously dedup'd to `[A]` and rejected. Now produces a 2-way "all identical" report. |
|
|
103
|
+
| README install lead | Section 4.2 now recommends a venv more strongly + explains why + gives `python -m ssmforge.cli` as the universal workaround. |
|
|
104
|
+
|
|
105
|
+
Plus 26 new tests (156 total).
|
|
106
|
+
|
|
85
107
|
### What's new in 0.2.0
|
|
86
108
|
|
|
87
109
|
| Feature | Why it matters |
|
|
@@ -252,7 +274,13 @@ If you don't have it:
|
|
|
252
274
|
- macOS: `brew install python@3.12`
|
|
253
275
|
- Windows: download from https://www.python.org/downloads/
|
|
254
276
|
|
|
255
|
-
### 4.2 Create a virtual environment (recommended)
|
|
277
|
+
### 4.2 Create a virtual environment (recommended — strongly)
|
|
278
|
+
|
|
279
|
+
**Use a venv.** It sidesteps the most common install problem on Windows
|
|
280
|
+
(`ssmforge: command not found` after pip install). With a venv, the
|
|
281
|
+
`ssmforge` script lands at `.venv\Scripts\ssmforge.exe` (Windows) or
|
|
282
|
+
`.venv/bin/ssmforge` (Linux/macOS), which is automatically on PATH after
|
|
283
|
+
you activate.
|
|
256
284
|
|
|
257
285
|
A venv keeps ssmforge and its dependencies isolated from system Python.
|
|
258
286
|
|
|
@@ -273,6 +301,15 @@ python -m venv .venv
|
|
|
273
301
|
You should see `(.venv)` in your prompt after activating. From here on,
|
|
274
302
|
`pip install` only affects this venv.
|
|
275
303
|
|
|
304
|
+
**Alternative: use `python -m ssmforge.cli`** as a workaround without a
|
|
305
|
+
venv. Works anywhere, doesn't need any PATH setup, but requires typing
|
|
306
|
+
`python -m ssmforge.cli` instead of just `ssmforge`.
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
python -m ssmforge.cli --version
|
|
310
|
+
python -m ssmforge.cli arch hf-internal-testing/tiny-random-LlamaForCausalLM --dry-run
|
|
311
|
+
```
|
|
312
|
+
|
|
276
313
|
### 4.3 Install ssmforge
|
|
277
314
|
|
|
278
315
|
```bash
|
|
@@ -416,6 +453,52 @@ JSON variant:
|
|
|
416
453
|
ssmforge doctor --format json
|
|
417
454
|
```
|
|
418
455
|
|
|
456
|
+
#### `ssmforge doctor --check-install`
|
|
457
|
+
|
|
458
|
+
Run install checks (PATH, scripts location) and exit non-zero on issues.
|
|
459
|
+
Useful in scripts or when troubleshooting "command not found":
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
ssmforge doctor --check-install
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
```
|
|
466
|
+
ssmforge doctor --check-install (0.2.1)
|
|
467
|
+
--------------------------------------------------
|
|
468
|
+
✓ ssmforge command on PATH: True
|
|
469
|
+
python: C:\Users\netge\.venv\Scripts\python.exe
|
|
470
|
+
platform: win32
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
If `ssmforge` isn't on PATH, you get a fix-hint block:
|
|
474
|
+
|
|
475
|
+
```
|
|
476
|
+
ssmforge doctor --check-install (0.2.1)
|
|
477
|
+
--------------------------------------------------
|
|
478
|
+
✗ ssmforge command on PATH: False
|
|
479
|
+
python: C:\Python314\python.exe
|
|
480
|
+
platform: win32
|
|
481
|
+
|
|
482
|
+
The 'ssmforge' script was installed to:
|
|
483
|
+
C:\Users\netge\AppData\Roaming\Python\Python314\Scripts\ssmforge.exe
|
|
484
|
+
but that folder is not on PATH.
|
|
485
|
+
|
|
486
|
+
Quick fix (current shell):
|
|
487
|
+
export PATH="/c/Users/netge/AppData/Roaming/Python/Python314/Scripts:$PATH"
|
|
488
|
+
|
|
489
|
+
Permanent fix (PowerShell, restart shell after):
|
|
490
|
+
[Environment]::SetEnvironmentVariable("PATH", "<scripts>;" + [Environment]::GetEnvironmentVariable("PATH", "User"), "User")
|
|
491
|
+
|
|
492
|
+
Or just use: python -m ssmforge.cli
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
JSON variant:
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
ssmforge doctor --check-install --format json
|
|
499
|
+
# {"ssmforge_command_on_path": false, "fix_hint": "...", ...}
|
|
500
|
+
```
|
|
501
|
+
|
|
419
502
|
### `ssmforge arch MODEL`
|
|
420
503
|
|
|
421
504
|
The main command. Inspect a HuggingFace model.
|
|
@@ -436,7 +519,7 @@ ssmforge arch <model_id_or_path> [options]
|
|
|
436
519
|
| `--fields name1,name2` | | Subset output to comma-separated field names. Dotted paths supported (e.g. `quirks.attention_bias`) | all |
|
|
437
520
|
| `--profile` | | Emit only the profile section (family, attention_type, mlp_type, norm_type, descriptors) | full report |
|
|
438
521
|
| `--only-different` | | In `--compare` mode, hide the "Identical across all models" section | show identical |
|
|
439
|
-
| `--graph` | | Render a text-based decision-graph in your terminal. Single-model shows the full pipeline with decisions inline. `--compare --graph` shows an N-way decision table. | JSON |
|
|
522
|
+
| `--graph` | | Render a text-based decision-graph in your terminal. Single-model shows the full pipeline with decisions inline. `--compare --graph` shows an N-way decision table. Honors `--format` (`text`, `json`, `markdown`/`md`) for JSON pipeline consumption and GFM-friendly docs. | JSON |
|
|
440
523
|
|
|
441
524
|
**Examples:**
|
|
442
525
|
|
|
@@ -1114,7 +1197,7 @@ use a newer Python.
|
|
|
1114
1197
|
**`pip install ssmforge` succeeds but `ssmforge` command not found**
|
|
1115
1198
|
|
|
1116
1199
|
The install put the script in a directory not on your PATH. Activate
|
|
1117
|
-
your venv (see [4.2](#42-create-a-virtual-environment-recommended)) or
|
|
1200
|
+
your venv (see [4.2](#42-create-a-virtual-environment-recommended-strongly)) or
|
|
1118
1201
|
check `pip show ssmforge` for the install location.
|
|
1119
1202
|
|
|
1120
1203
|
**`ssmforge: command not found` after `pip install` succeeds (Windows)**
|
|
@@ -1317,7 +1400,143 @@ install.
|
|
|
1317
1400
|
|
|
1318
1401
|
## 16. Update log
|
|
1319
1402
|
|
|
1320
|
-
### v0.2.
|
|
1403
|
+
### v0.2.2 (current) — 2026-09-23
|
|
1404
|
+
|
|
1405
|
+
**Bug fix: `--output PATH` directory validation**
|
|
1406
|
+
|
|
1407
|
+
When `--output PATH` points to a non-writable location, users were getting
|
|
1408
|
+
either a generic shell `Permission denied` (when using shell redirection)
|
|
1409
|
+
or an opaque Python `OSError` (when using `--output` directly). Now
|
|
1410
|
+
ssmforge pre-flight checks the parent directory and prints a friendly
|
|
1411
|
+
hint pointing at writable alternatives.
|
|
1412
|
+
|
|
1413
|
+
**Before:**
|
|
1414
|
+
```
|
|
1415
|
+
$ python -m ssmforge.cli arch X --graph --format markdown > q.md
|
|
1416
|
+
bash: q.md: Permission denied
|
|
1417
|
+
|
|
1418
|
+
$ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
|
|
1419
|
+
Error: cannot write to 'C:\\q.md': [Errno 13] Permission denied: 'C:\\q.md'
|
|
1420
|
+
```
|
|
1421
|
+
|
|
1422
|
+
**After:**
|
|
1423
|
+
```
|
|
1424
|
+
$ python -m ssmforge.cli arch X --graph --format markdown > q.md
|
|
1425
|
+
# (still works in any shell that allows the redirect)
|
|
1426
|
+
|
|
1427
|
+
$ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
|
|
1428
|
+
Error: cannot write to directory: C:\
|
|
1429
|
+
Permission denied.
|
|
1430
|
+
Try a writable location like:
|
|
1431
|
+
--output ./report.md (current directory)
|
|
1432
|
+
--output ~/report.md (your home directory)
|
|
1433
|
+
--output $TMPDIR/report.md (system temp)
|
|
1434
|
+
```
|
|
1435
|
+
|
|
1436
|
+
Tests: 162 passed (was 156). 6 new tests for `_check_output_path`
|
|
1437
|
+
(returns (None, None) for None / '-' paths, validates writability,
|
|
1438
|
+
emits helpful hints for missing or read-only parents).
|
|
1439
|
+
|
|
1440
|
+
### v0.2.1 — 2026-09-23
|
|
1441
|
+
|
|
1442
|
+
**New feature: `doctor --check-install`**
|
|
1443
|
+
|
|
1444
|
+
Run install checks (PATH, scripts location, platform) and exit non-zero
|
|
1445
|
+
when something is wrong. Use in scripts or when troubleshooting:
|
|
1446
|
+
|
|
1447
|
+
```bash
|
|
1448
|
+
ssmforge doctor --check-install
|
|
1449
|
+
# prints ✓ or ✗ + fix hint
|
|
1450
|
+
echo $? # 0 = good, 1 = something off
|
|
1451
|
+
```
|
|
1452
|
+
|
|
1453
|
+
The fix-hint output is a copy-pasteable shell command — exactly the
|
|
1454
|
+
right `export PATH=...` or `[Environment]::SetEnvironmentVariable(...)`
|
|
1455
|
+
line for your platform.
|
|
1456
|
+
|
|
1457
|
+
**New: one-time PATH warning on stderr**
|
|
1458
|
+
|
|
1459
|
+
When ssmforge detects it's been installed off-PATH, every `ssmforge
|
|
1460
|
+
arch ...` call prints a one-time hint to stderr:
|
|
1461
|
+
|
|
1462
|
+
```
|
|
1463
|
+
Note: 'ssmforge' is not on your PATH for `python -m ssmforge.cli` users.
|
|
1464
|
+
This is normal if you're running via 'python -m ssmforge.cli'.
|
|
1465
|
+
If 'ssmforge --version' fails, see: https://github.com/lordxmen2k/SSMForge#troubleshooting
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
This is suppressed:
|
|
1469
|
+
- when ssmforge IS on PATH
|
|
1470
|
+
- when the user explicitly runs `ssmforge doctor ...`
|
|
1471
|
+
- when `SSMFORGE_NO_PATH_WARN=1` is set in the env
|
|
1472
|
+
|
|
1473
|
+
**README install lead**
|
|
1474
|
+
|
|
1475
|
+
Section 4.2 (Create a virtual environment) now leads with a stronger
|
|
1476
|
+
recommendation and a fallback path (`python -m ssmforge.cli`). No
|
|
1477
|
+
changes to the install command itself — just clearer context.
|
|
1478
|
+
|
|
1479
|
+
**Bug fix: Qwen2 attention_bias false positive**
|
|
1480
|
+
|
|
1481
|
+
Previously, `scan_state_dict` set `attention_bias=True` whenever
|
|
1482
|
+
`*self_attn.*.bias` tensors existed in the state dict. Qwen2 ships
|
|
1483
|
+
zero-initialized bias tensors (vestigial, never used) and was
|
|
1484
|
+
incorrectly reported as having attention biases.
|
|
1485
|
+
|
|
1486
|
+
Now: `attention_bias` is set to True only when **either** the config
|
|
1487
|
+
explicitly says `attention_bias=True` **or** the bias tensors contain
|
|
1488
|
+
non-zero values. The `bias_keys_found` list still records that the
|
|
1489
|
+
tensors exist for transparency.
|
|
1490
|
+
|
|
1491
|
+
Tests:
|
|
1492
|
+
- `test_scan_detects_attention_bias` (updated) — zero biases → False
|
|
1493
|
+
- `test_scan_detects_nonzero_attention_bias` (new) — non-zero → True
|
|
1494
|
+
- `test_reports_attention_bias_from_state_dict_when_config_missing`
|
|
1495
|
+
(updated) — config.attention_bias=None + zero biases → False
|
|
1496
|
+
|
|
1497
|
+
**Bug fix: `--compare A A` no longer rejected**
|
|
1498
|
+
|
|
1499
|
+
Previously `--compare A A` was dedup'd to `[A]` and rejected with
|
|
1500
|
+
"requires at least 2 models". Now produces a valid 2-way "all identical"
|
|
1501
|
+
report.
|
|
1502
|
+
|
|
1503
|
+
**Feature: `--graph` honors `--format {text,json,markdown}`**
|
|
1504
|
+
|
|
1505
|
+
Three output modes for `--graph`:
|
|
1506
|
+
- `--format text` (default for `--graph`) — ASCII with box-drawing
|
|
1507
|
+
- `--format json` — structured pipeline + decisions for piping into
|
|
1508
|
+
other tools
|
|
1509
|
+
- `--format markdown`/`md` — GitHub-flavored Markdown tables for
|
|
1510
|
+
embedding in docs, Issues, PRs
|
|
1511
|
+
|
|
1512
|
+
All three work for both single-model and `--compare --graph` modes.
|
|
1513
|
+
|
|
1514
|
+
**Bug fix: `--graph` ASCII hierarchy**
|
|
1515
|
+
|
|
1516
|
+
The previous box-drawing had two parallel rails (`├─` and `▼`) that
|
|
1517
|
+
suggested two unrelated flows. Replaced with single-rail `▼` flow and
|
|
1518
|
+
`╭╮╰╯` panels for ATTENTION and MLP blocks. Decision-tree style
|
|
1519
|
+
`├─/└─` inside each panel. Renders correctly in any terminal.
|
|
1520
|
+
|
|
1521
|
+
**Tests: 156 passed** (was 142). 14 new tests:
|
|
1522
|
+
- 12 from `test_v021_check_install.py` (PATH detection, doctor
|
|
1523
|
+
--check-install, main() integration)
|
|
1524
|
+
- 1 from `test_v017_compare.py` (`--compare A A` regression)
|
|
1525
|
+
- 1 from `test_analyze.py` (nonzero attention_bias detection)
|
|
1526
|
+
- 13 from `test_graph.py` (JSON/Markdown formatters, GFM
|
|
1527
|
+
compatibility, edge cases)
|
|
1528
|
+
- (some overlap with existing test updates for attention_bias fix)
|
|
1529
|
+
|
|
1530
|
+
Tests: 142 passed (was 130). 12 new tests:
|
|
1531
|
+
- `_check_ssmforge_on_path`: returns correct tuple, finds off-path
|
|
1532
|
+
install, returns no fix when on PATH
|
|
1533
|
+
- `_warn_path_once`: writes to stderr when off-path, respects env
|
|
1534
|
+
var, skips when on PATH
|
|
1535
|
+
- `main()` integration: suppresses warning for doctor, emits for arch
|
|
1536
|
+
- `doctor --check-install`: text output on/off PATH, JSON output,
|
|
1537
|
+
exit codes (0 / 1), back-compat with default `doctor`
|
|
1538
|
+
|
|
1539
|
+
### v0.2.0 — 2026-09-22
|
|
1321
1540
|
|
|
1322
1541
|
**New feature: `--graph`**
|
|
1323
1542
|
|
|
@@ -59,6 +59,28 @@ visible *before* you spend the next hour finding out the hard way.
|
|
|
59
59
|
It does **not** modify the model. It does **not** run inference. It only
|
|
60
60
|
inspects.
|
|
61
61
|
|
|
62
|
+
### What's new in 0.2.2
|
|
63
|
+
|
|
64
|
+
| Fix | What was broken |
|
|
65
|
+
|-----|-----------------|
|
|
66
|
+
| `--output PATH` with bad parent dir | Previously got a generic `bash: Permission denied` (when redirecting) or a Python traceback (when using `--output`). Now pre-flight checks the parent directory, prints a clear hint pointing at writable locations like `./` and `~/`, then exits 1. |
|
|
67
|
+
|
|
68
|
+
Plus 6 new tests (162 total). Tiny release — main bug fix only.
|
|
69
|
+
|
|
70
|
+
### What's new in 0.2.1
|
|
71
|
+
|
|
72
|
+
| Feature | Why it matters |
|
|
73
|
+
|---------|----------------|
|
|
74
|
+
| `doctor --check-install` | Diagnoses "ssmforge: command not found" in one command. Prints `✓` when on PATH, `✗` + a copy-pasteable fix hint when not. Exits non-zero so you can use it in scripts. |
|
|
75
|
+
| One-time PATH warning | First invocation when `ssmforge` is off-PATH prints a hint to stderr pointing at `python -m ssmforge.cli`. Suppressed by `SSMFORGE_NO_PATH_WARN=1`. Skipped for `doctor` so its output stays clean. |
|
|
76
|
+
| `--graph --format {text,json,markdown}` | `--graph` now respects `--format`. Single + compare modes emit ASCII (text), structured JSON (for pipelines), or GitHub-flavored Markdown (for docs/Issues). |
|
|
77
|
+
| `--graph` ASCII cleanup | Box-drawing hierarchy fixed: single-rail `▼` flow + box `╭╮╰╯` panels for ATTENTION and MLP, `├─/└─` decision-tree style inside. |
|
|
78
|
+
| Qwen2 attention_bias fixed | `config.attention_bias=None` + zero bias tensors (Qwen2's vestigial biases) no longer reports `attention_bias=True`. Now requires either config explicit True OR non-zero bias values. |
|
|
79
|
+
| `--compare A A` is now valid | Was previously dedup'd to `[A]` and rejected. Now produces a 2-way "all identical" report. |
|
|
80
|
+
| README install lead | Section 4.2 now recommends a venv more strongly + explains why + gives `python -m ssmforge.cli` as the universal workaround. |
|
|
81
|
+
|
|
82
|
+
Plus 26 new tests (156 total).
|
|
83
|
+
|
|
62
84
|
### What's new in 0.2.0
|
|
63
85
|
|
|
64
86
|
| Feature | Why it matters |
|
|
@@ -229,7 +251,13 @@ If you don't have it:
|
|
|
229
251
|
- macOS: `brew install python@3.12`
|
|
230
252
|
- Windows: download from https://www.python.org/downloads/
|
|
231
253
|
|
|
232
|
-
### 4.2 Create a virtual environment (recommended)
|
|
254
|
+
### 4.2 Create a virtual environment (recommended — strongly)
|
|
255
|
+
|
|
256
|
+
**Use a venv.** It sidesteps the most common install problem on Windows
|
|
257
|
+
(`ssmforge: command not found` after pip install). With a venv, the
|
|
258
|
+
`ssmforge` script lands at `.venv\Scripts\ssmforge.exe` (Windows) or
|
|
259
|
+
`.venv/bin/ssmforge` (Linux/macOS), which is automatically on PATH after
|
|
260
|
+
you activate.
|
|
233
261
|
|
|
234
262
|
A venv keeps ssmforge and its dependencies isolated from system Python.
|
|
235
263
|
|
|
@@ -250,6 +278,15 @@ python -m venv .venv
|
|
|
250
278
|
You should see `(.venv)` in your prompt after activating. From here on,
|
|
251
279
|
`pip install` only affects this venv.
|
|
252
280
|
|
|
281
|
+
**Alternative: use `python -m ssmforge.cli`** as a workaround without a
|
|
282
|
+
venv. Works anywhere, doesn't need any PATH setup, but requires typing
|
|
283
|
+
`python -m ssmforge.cli` instead of just `ssmforge`.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
python -m ssmforge.cli --version
|
|
287
|
+
python -m ssmforge.cli arch hf-internal-testing/tiny-random-LlamaForCausalLM --dry-run
|
|
288
|
+
```
|
|
289
|
+
|
|
253
290
|
### 4.3 Install ssmforge
|
|
254
291
|
|
|
255
292
|
```bash
|
|
@@ -393,6 +430,52 @@ JSON variant:
|
|
|
393
430
|
ssmforge doctor --format json
|
|
394
431
|
```
|
|
395
432
|
|
|
433
|
+
#### `ssmforge doctor --check-install`
|
|
434
|
+
|
|
435
|
+
Run install checks (PATH, scripts location) and exit non-zero on issues.
|
|
436
|
+
Useful in scripts or when troubleshooting "command not found":
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
ssmforge doctor --check-install
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
ssmforge doctor --check-install (0.2.1)
|
|
444
|
+
--------------------------------------------------
|
|
445
|
+
✓ ssmforge command on PATH: True
|
|
446
|
+
python: C:\Users\netge\.venv\Scripts\python.exe
|
|
447
|
+
platform: win32
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
If `ssmforge` isn't on PATH, you get a fix-hint block:
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
ssmforge doctor --check-install (0.2.1)
|
|
454
|
+
--------------------------------------------------
|
|
455
|
+
✗ ssmforge command on PATH: False
|
|
456
|
+
python: C:\Python314\python.exe
|
|
457
|
+
platform: win32
|
|
458
|
+
|
|
459
|
+
The 'ssmforge' script was installed to:
|
|
460
|
+
C:\Users\netge\AppData\Roaming\Python\Python314\Scripts\ssmforge.exe
|
|
461
|
+
but that folder is not on PATH.
|
|
462
|
+
|
|
463
|
+
Quick fix (current shell):
|
|
464
|
+
export PATH="/c/Users/netge/AppData/Roaming/Python/Python314/Scripts:$PATH"
|
|
465
|
+
|
|
466
|
+
Permanent fix (PowerShell, restart shell after):
|
|
467
|
+
[Environment]::SetEnvironmentVariable("PATH", "<scripts>;" + [Environment]::GetEnvironmentVariable("PATH", "User"), "User")
|
|
468
|
+
|
|
469
|
+
Or just use: python -m ssmforge.cli
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
JSON variant:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
ssmforge doctor --check-install --format json
|
|
476
|
+
# {"ssmforge_command_on_path": false, "fix_hint": "...", ...}
|
|
477
|
+
```
|
|
478
|
+
|
|
396
479
|
### `ssmforge arch MODEL`
|
|
397
480
|
|
|
398
481
|
The main command. Inspect a HuggingFace model.
|
|
@@ -413,7 +496,7 @@ ssmforge arch <model_id_or_path> [options]
|
|
|
413
496
|
| `--fields name1,name2` | | Subset output to comma-separated field names. Dotted paths supported (e.g. `quirks.attention_bias`) | all |
|
|
414
497
|
| `--profile` | | Emit only the profile section (family, attention_type, mlp_type, norm_type, descriptors) | full report |
|
|
415
498
|
| `--only-different` | | In `--compare` mode, hide the "Identical across all models" section | show identical |
|
|
416
|
-
| `--graph` | | Render a text-based decision-graph in your terminal. Single-model shows the full pipeline with decisions inline. `--compare --graph` shows an N-way decision table. | JSON |
|
|
499
|
+
| `--graph` | | Render a text-based decision-graph in your terminal. Single-model shows the full pipeline with decisions inline. `--compare --graph` shows an N-way decision table. Honors `--format` (`text`, `json`, `markdown`/`md`) for JSON pipeline consumption and GFM-friendly docs. | JSON |
|
|
417
500
|
|
|
418
501
|
**Examples:**
|
|
419
502
|
|
|
@@ -1091,7 +1174,7 @@ use a newer Python.
|
|
|
1091
1174
|
**`pip install ssmforge` succeeds but `ssmforge` command not found**
|
|
1092
1175
|
|
|
1093
1176
|
The install put the script in a directory not on your PATH. Activate
|
|
1094
|
-
your venv (see [4.2](#42-create-a-virtual-environment-recommended)) or
|
|
1177
|
+
your venv (see [4.2](#42-create-a-virtual-environment-recommended-strongly)) or
|
|
1095
1178
|
check `pip show ssmforge` for the install location.
|
|
1096
1179
|
|
|
1097
1180
|
**`ssmforge: command not found` after `pip install` succeeds (Windows)**
|
|
@@ -1294,7 +1377,143 @@ install.
|
|
|
1294
1377
|
|
|
1295
1378
|
## 16. Update log
|
|
1296
1379
|
|
|
1297
|
-
### v0.2.
|
|
1380
|
+
### v0.2.2 (current) — 2026-09-23
|
|
1381
|
+
|
|
1382
|
+
**Bug fix: `--output PATH` directory validation**
|
|
1383
|
+
|
|
1384
|
+
When `--output PATH` points to a non-writable location, users were getting
|
|
1385
|
+
either a generic shell `Permission denied` (when using shell redirection)
|
|
1386
|
+
or an opaque Python `OSError` (when using `--output` directly). Now
|
|
1387
|
+
ssmforge pre-flight checks the parent directory and prints a friendly
|
|
1388
|
+
hint pointing at writable alternatives.
|
|
1389
|
+
|
|
1390
|
+
**Before:**
|
|
1391
|
+
```
|
|
1392
|
+
$ python -m ssmforge.cli arch X --graph --format markdown > q.md
|
|
1393
|
+
bash: q.md: Permission denied
|
|
1394
|
+
|
|
1395
|
+
$ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
|
|
1396
|
+
Error: cannot write to 'C:\\q.md': [Errno 13] Permission denied: 'C:\\q.md'
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
**After:**
|
|
1400
|
+
```
|
|
1401
|
+
$ python -m ssmforge.cli arch X --graph --format markdown > q.md
|
|
1402
|
+
# (still works in any shell that allows the redirect)
|
|
1403
|
+
|
|
1404
|
+
$ python -m ssmforge.cli arch X --graph --format markdown --output C:\q.md
|
|
1405
|
+
Error: cannot write to directory: C:\
|
|
1406
|
+
Permission denied.
|
|
1407
|
+
Try a writable location like:
|
|
1408
|
+
--output ./report.md (current directory)
|
|
1409
|
+
--output ~/report.md (your home directory)
|
|
1410
|
+
--output $TMPDIR/report.md (system temp)
|
|
1411
|
+
```
|
|
1412
|
+
|
|
1413
|
+
Tests: 162 passed (was 156). 6 new tests for `_check_output_path`
|
|
1414
|
+
(returns (None, None) for None / '-' paths, validates writability,
|
|
1415
|
+
emits helpful hints for missing or read-only parents).
|
|
1416
|
+
|
|
1417
|
+
### v0.2.1 — 2026-09-23
|
|
1418
|
+
|
|
1419
|
+
**New feature: `doctor --check-install`**
|
|
1420
|
+
|
|
1421
|
+
Run install checks (PATH, scripts location, platform) and exit non-zero
|
|
1422
|
+
when something is wrong. Use in scripts or when troubleshooting:
|
|
1423
|
+
|
|
1424
|
+
```bash
|
|
1425
|
+
ssmforge doctor --check-install
|
|
1426
|
+
# prints ✓ or ✗ + fix hint
|
|
1427
|
+
echo $? # 0 = good, 1 = something off
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
The fix-hint output is a copy-pasteable shell command — exactly the
|
|
1431
|
+
right `export PATH=...` or `[Environment]::SetEnvironmentVariable(...)`
|
|
1432
|
+
line for your platform.
|
|
1433
|
+
|
|
1434
|
+
**New: one-time PATH warning on stderr**
|
|
1435
|
+
|
|
1436
|
+
When ssmforge detects it's been installed off-PATH, every `ssmforge
|
|
1437
|
+
arch ...` call prints a one-time hint to stderr:
|
|
1438
|
+
|
|
1439
|
+
```
|
|
1440
|
+
Note: 'ssmforge' is not on your PATH for `python -m ssmforge.cli` users.
|
|
1441
|
+
This is normal if you're running via 'python -m ssmforge.cli'.
|
|
1442
|
+
If 'ssmforge --version' fails, see: https://github.com/lordxmen2k/SSMForge#troubleshooting
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1445
|
+
This is suppressed:
|
|
1446
|
+
- when ssmforge IS on PATH
|
|
1447
|
+
- when the user explicitly runs `ssmforge doctor ...`
|
|
1448
|
+
- when `SSMFORGE_NO_PATH_WARN=1` is set in the env
|
|
1449
|
+
|
|
1450
|
+
**README install lead**
|
|
1451
|
+
|
|
1452
|
+
Section 4.2 (Create a virtual environment) now leads with a stronger
|
|
1453
|
+
recommendation and a fallback path (`python -m ssmforge.cli`). No
|
|
1454
|
+
changes to the install command itself — just clearer context.
|
|
1455
|
+
|
|
1456
|
+
**Bug fix: Qwen2 attention_bias false positive**
|
|
1457
|
+
|
|
1458
|
+
Previously, `scan_state_dict` set `attention_bias=True` whenever
|
|
1459
|
+
`*self_attn.*.bias` tensors existed in the state dict. Qwen2 ships
|
|
1460
|
+
zero-initialized bias tensors (vestigial, never used) and was
|
|
1461
|
+
incorrectly reported as having attention biases.
|
|
1462
|
+
|
|
1463
|
+
Now: `attention_bias` is set to True only when **either** the config
|
|
1464
|
+
explicitly says `attention_bias=True` **or** the bias tensors contain
|
|
1465
|
+
non-zero values. The `bias_keys_found` list still records that the
|
|
1466
|
+
tensors exist for transparency.
|
|
1467
|
+
|
|
1468
|
+
Tests:
|
|
1469
|
+
- `test_scan_detects_attention_bias` (updated) — zero biases → False
|
|
1470
|
+
- `test_scan_detects_nonzero_attention_bias` (new) — non-zero → True
|
|
1471
|
+
- `test_reports_attention_bias_from_state_dict_when_config_missing`
|
|
1472
|
+
(updated) — config.attention_bias=None + zero biases → False
|
|
1473
|
+
|
|
1474
|
+
**Bug fix: `--compare A A` no longer rejected**
|
|
1475
|
+
|
|
1476
|
+
Previously `--compare A A` was dedup'd to `[A]` and rejected with
|
|
1477
|
+
"requires at least 2 models". Now produces a valid 2-way "all identical"
|
|
1478
|
+
report.
|
|
1479
|
+
|
|
1480
|
+
**Feature: `--graph` honors `--format {text,json,markdown}`**
|
|
1481
|
+
|
|
1482
|
+
Three output modes for `--graph`:
|
|
1483
|
+
- `--format text` (default for `--graph`) — ASCII with box-drawing
|
|
1484
|
+
- `--format json` — structured pipeline + decisions for piping into
|
|
1485
|
+
other tools
|
|
1486
|
+
- `--format markdown`/`md` — GitHub-flavored Markdown tables for
|
|
1487
|
+
embedding in docs, Issues, PRs
|
|
1488
|
+
|
|
1489
|
+
All three work for both single-model and `--compare --graph` modes.
|
|
1490
|
+
|
|
1491
|
+
**Bug fix: `--graph` ASCII hierarchy**
|
|
1492
|
+
|
|
1493
|
+
The previous box-drawing had two parallel rails (`├─` and `▼`) that
|
|
1494
|
+
suggested two unrelated flows. Replaced with single-rail `▼` flow and
|
|
1495
|
+
`╭╮╰╯` panels for ATTENTION and MLP blocks. Decision-tree style
|
|
1496
|
+
`├─/└─` inside each panel. Renders correctly in any terminal.
|
|
1497
|
+
|
|
1498
|
+
**Tests: 156 passed** (was 142). 14 new tests:
|
|
1499
|
+
- 12 from `test_v021_check_install.py` (PATH detection, doctor
|
|
1500
|
+
--check-install, main() integration)
|
|
1501
|
+
- 1 from `test_v017_compare.py` (`--compare A A` regression)
|
|
1502
|
+
- 1 from `test_analyze.py` (nonzero attention_bias detection)
|
|
1503
|
+
- 13 from `test_graph.py` (JSON/Markdown formatters, GFM
|
|
1504
|
+
compatibility, edge cases)
|
|
1505
|
+
- (some overlap with existing test updates for attention_bias fix)
|
|
1506
|
+
|
|
1507
|
+
Tests: 142 passed (was 130). 12 new tests:
|
|
1508
|
+
- `_check_ssmforge_on_path`: returns correct tuple, finds off-path
|
|
1509
|
+
install, returns no fix when on PATH
|
|
1510
|
+
- `_warn_path_once`: writes to stderr when off-path, respects env
|
|
1511
|
+
var, skips when on PATH
|
|
1512
|
+
- `main()` integration: suppresses warning for doctor, emits for arch
|
|
1513
|
+
- `doctor --check-install`: text output on/off PATH, JSON output,
|
|
1514
|
+
exit codes (0 / 1), back-compat with default `doctor`
|
|
1515
|
+
|
|
1516
|
+
### v0.2.0 — 2026-09-22
|
|
1298
1517
|
|
|
1299
1518
|
**New feature: `--graph`**
|
|
1300
1519
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ssmforge"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Standalone HF architecture analyzer (`ssmforge arch`). Inspects any HuggingFace model and reports architectural quirks — attention biases, fused QKV/gate-up, tied embeddings, GQA, MQA, MoE, sliding window, LayerScale, soft-capping, partial RoPE, MLP type, norm type. Outputs structured JSON + human-readable summary."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -34,7 +34,14 @@ from ssmforge.analyze.state_dict_scan import (
|
|
|
34
34
|
from ssmforge.analyze.summary import render_summary
|
|
35
35
|
from ssmforge.analyze.markdown_render import format_report_markdown
|
|
36
36
|
from ssmforge.analyze.diff import diff_reports, compare_reports, format_compare_markdown
|
|
37
|
-
from ssmforge.analyze.graph import
|
|
37
|
+
from ssmforge.analyze.graph import (
|
|
38
|
+
render_graph_text,
|
|
39
|
+
render_graph_compare,
|
|
40
|
+
render_graph_json,
|
|
41
|
+
render_graph_compare_json,
|
|
42
|
+
render_graph_markdown,
|
|
43
|
+
render_graph_compare_markdown,
|
|
44
|
+
)
|
|
38
45
|
|
|
39
46
|
__all__ = [
|
|
40
47
|
"build_report",
|