model-unfolder 0.2.7__tar.gz → 0.2.8__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.
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/PKG-INFO +2 -2
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/README.md +1 -1
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/__init__.py +31 -5
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/__init__.py +8 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/attention.py +21 -6
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/descriptions.py +6 -4
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/parser.py +553 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/__init__.py +6 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/accessors.py +71 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/audio.py +124 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/builder.py +33 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/detect.py +182 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/fusion.py +115 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/schema.py +17 -0
- model_unfolder-0.2.8/model_unfolder/adapters/transformer/special_parts/modalities/vision.py +380 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/diagram.py +20 -2
- model_unfolder-0.2.8/model_unfolder/evidence/__init__.py +13 -0
- model_unfolder-0.2.8/model_unfolder/evidence/ast_scanner.py +87 -0
- model_unfolder-0.2.8/model_unfolder/evidence/inspector.py +28 -0
- model_unfolder-0.2.8/model_unfolder/evidence/models.py +169 -0
- model_unfolder-0.2.8/model_unfolder/evidence/patterns.py +392 -0
- model_unfolder-0.2.8/model_unfolder/evidence/sources.py +318 -0
- model_unfolder-0.2.8/model_unfolder/evidence/validate.py +153 -0
- model_unfolder-0.2.8/model_unfolder/expanded/__init__.py +89 -0
- model_unfolder-0.2.8/model_unfolder/expanded/attention.py +185 -0
- model_unfolder-0.2.8/model_unfolder/expanded/block_graph.py +41 -0
- model_unfolder-0.2.8/model_unfolder/expanded/code_evidence.py +62 -0
- model_unfolder-0.2.8/model_unfolder/expanded/ffn.py +85 -0
- model_unfolder-0.2.8/model_unfolder/expanded/grouping.py +90 -0
- model_unfolder-0.2.8/model_unfolder/expanded/layer_group.py +39 -0
- model_unfolder-0.2.8/model_unfolder/expanded/modalities.py +72 -0
- model_unfolder-0.2.8/model_unfolder/expanded/norms.py +13 -0
- model_unfolder-0.2.8/model_unfolder/expanded/ops.py +41 -0
- model_unfolder-0.2.8/model_unfolder/expanded/pathways.py +29 -0
- model_unfolder-0.2.8/model_unfolder/expanded/residual.py +25 -0
- model_unfolder-0.2.8/model_unfolder/expanded/sections.py +84 -0
- model_unfolder-0.2.8/model_unfolder/expanded/stack.py +59 -0
- model_unfolder-0.2.8/model_unfolder/expanded/utils.py +49 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/labels.py +4 -3
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/parser.py +47 -2
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/__init__.py +20 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/common.py +121 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/grouped_query.py +15 -8
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/latent.py +7 -4
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/multi_head.py +14 -8
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/multi_query.py +22 -8
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/attention_types/sliding_window.py +76 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modalities.py +16 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/__init__.py +15 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/audio.py +31 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/common.py +80 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/fusion_cross_attention.py +62 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/fusion_grid.py +119 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/fusion_placeholder.py +208 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/video.py +41 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/modality_views/vision.py +43 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/block_views/registry.py +60 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/cards.py +16 -1
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/document.py +3 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/evidence.py +114 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/interactions.py +15 -10
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/metadata.py +3 -0
- model_unfolder-0.2.8/model_unfolder/renderers/html/metadata_modalities.py +634 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/styles.py +75 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/svg.py +19 -7
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/theme.py +1 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/views.py +31 -11
- model_unfolder-0.2.8/model_unfolder/renderers/html/views_modalities.py +161 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder.egg-info/PKG-INFO +2 -2
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder.egg-info/SOURCES.txt +47 -18
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/pyproject.toml +1 -1
- model_unfolder-0.2.8/tests/test_code_evidence.py +460 -0
- model_unfolder-0.2.8/tests/test_expanded_json.py +530 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/tests/test_smoke.py +346 -88
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/__init__.py +0 -5
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/__init__.py +0 -26
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/cohere.py +0 -106
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/deepseek.py +0 -106
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/falcon.py +0 -183
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/fallback.py +0 -192
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/gemma/__init__.py +0 -26
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/gemma/gemma2.py +0 -101
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/gemma/gemma3.py +0 -137
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/gemma/gemma4.py +0 -200
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/gpt_neox.py +0 -114
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/jamba.py +0 -126
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/llama.py +0 -138
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/minimax.py +0 -99
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/mistral.py +0 -119
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/qwen.py +0 -148
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/recurrent_gemma.py +0 -103
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/rwkv.py +0 -74
- model_unfolder-0.2.7/model_unfolder/adapters/transformer/families/zamba.py +0 -127
- model_unfolder-0.2.7/model_unfolder/renderers/html/block_views/__init__.py +0 -38
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/LICENSE +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/custom/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/diffusor/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/assembly.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/feed_forward.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/layers.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/blocks/model.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/common.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/special_parts/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/adapters/transformer/special_parts/per_layer_embedding.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/html_renderer.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/ir.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/params.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/__init__.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/linear.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/rwkv.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/attention_types/state_space.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/feed_forward.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/mixture_of_experts.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/block_views/per_layer_embedding.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/sections.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder/renderers/html/utils.py +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder.egg-info/dependency_links.txt +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder.egg-info/requires.txt +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/model_unfolder.egg-info/top_level.txt +0 -0
- {model_unfolder-0.2.7 → model_unfolder-0.2.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: model-unfolder
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Unfold any HuggingFace transformer into an interactive architecture diagram, inline in Jupyter.
|
|
5
5
|
Author: model-unfolder contributors
|
|
6
6
|
License: Apache-2.0
|
|
@@ -95,7 +95,7 @@ No extra config in `model_unfolder` itself.
|
|
|
95
95
|
```python
|
|
96
96
|
diagram = unfold(cfg)
|
|
97
97
|
diagram.save("model.html") # standalone interactive HTML
|
|
98
|
-
diagram.save("model.json") #
|
|
98
|
+
diagram.save("model.json") # expanded architecture JSON (no rendering)
|
|
99
99
|
diagram.param_count() # {"total": ..., "active": ..., "per_layer": [...]}
|
|
100
100
|
diagram.to_ir() # full IR dict
|
|
101
101
|
```
|
|
@@ -71,7 +71,7 @@ No extra config in `model_unfolder` itself.
|
|
|
71
71
|
```python
|
|
72
72
|
diagram = unfold(cfg)
|
|
73
73
|
diagram.save("model.html") # standalone interactive HTML
|
|
74
|
-
diagram.save("model.json") #
|
|
74
|
+
diagram.save("model.json") # expanded architecture JSON (no rendering)
|
|
75
75
|
diagram.param_count() # {"total": ..., "active": ..., "per_layer": [...]}
|
|
76
76
|
diagram.to_ir() # full IR dict
|
|
77
77
|
```
|
|
@@ -11,6 +11,7 @@ Outside Jupyter::
|
|
|
11
11
|
diagram.save("kimi_k2.html")
|
|
12
12
|
"""
|
|
13
13
|
from .diagram import Diagram
|
|
14
|
+
from .evidence import inspect_model_code
|
|
14
15
|
from .parser import config_to_ir
|
|
15
16
|
from .ir import ModelIR, LayerSpec, AttentionSpec, FFNSpec, CrossLayerEdge
|
|
16
17
|
from .params import estimate_params
|
|
@@ -27,11 +28,19 @@ __all__ = [
|
|
|
27
28
|
"FFNSpec",
|
|
28
29
|
"CrossLayerEdge",
|
|
29
30
|
"config_to_ir",
|
|
31
|
+
"inspect_model_code",
|
|
30
32
|
"estimate_params",
|
|
31
33
|
]
|
|
32
34
|
|
|
33
35
|
|
|
34
|
-
def unfold(
|
|
36
|
+
def unfold(
|
|
37
|
+
cfg_or_id,
|
|
38
|
+
token=None,
|
|
39
|
+
*,
|
|
40
|
+
inspect_code: bool = False,
|
|
41
|
+
code_source: str = "local",
|
|
42
|
+
return_json: bool = False,
|
|
43
|
+
):
|
|
35
44
|
"""Unfold a transformer into a renderable architecture diagram.
|
|
36
45
|
|
|
37
46
|
Parameters
|
|
@@ -44,14 +53,31 @@ def unfold(cfg_or_id, token=None) -> Diagram:
|
|
|
44
53
|
Optional Hugging Face token used only when ``cfg_or_id`` is a model ID.
|
|
45
54
|
If omitted, ``HF_TOKEN`` and legacy Hugging Face token env vars are used
|
|
46
55
|
when present.
|
|
56
|
+
inspect_code
|
|
57
|
+
If True, attach static source-code evidence to the IR. The code scanner
|
|
58
|
+
parses modeling files as text/AST and does not execute model code.
|
|
59
|
+
code_source
|
|
60
|
+
Source for code inspection: ``"local"`` (installed transformers),
|
|
61
|
+
``"path"``, ``"hub"``, ``"auto"``, or a local file/directory path.
|
|
62
|
+
return_json
|
|
63
|
+
If True, return the expanded architecture JSON dict instead of the
|
|
64
|
+
renderable ``Diagram``. The JSON uses stable structural fields for
|
|
65
|
+
dimensions, projections, layer groups, operation graphs, cache behavior,
|
|
66
|
+
and trace paths instead of renderer labels/descriptions.
|
|
47
67
|
|
|
48
68
|
Returns
|
|
49
69
|
-------
|
|
50
|
-
Diagram
|
|
51
|
-
|
|
70
|
+
Diagram | dict
|
|
71
|
+
``Diagram`` by default; ``dict`` when ``return_json=True``.
|
|
52
72
|
"""
|
|
53
|
-
ir = config_to_ir(
|
|
54
|
-
|
|
73
|
+
ir = config_to_ir(
|
|
74
|
+
cfg_or_id,
|
|
75
|
+
token=token,
|
|
76
|
+
inspect_code=inspect_code,
|
|
77
|
+
code_source=code_source,
|
|
78
|
+
)
|
|
79
|
+
diagram = Diagram(ir)
|
|
80
|
+
return diagram.to_json() if return_json else diagram
|
|
55
81
|
|
|
56
82
|
|
|
57
83
|
# friendly alias
|
|
@@ -48,12 +48,18 @@ def _sdpa_child_blocks(attention: AttentionSpec, hidden_size: int) -> list[dict]
|
|
|
48
48
|
{
|
|
49
49
|
"id": "k_proj",
|
|
50
50
|
"title": "Key projection",
|
|
51
|
-
"description":
|
|
51
|
+
"description": (
|
|
52
|
+
f"Linear; {hidden} -> {kv_out} ({num_kv_heads} KV-heads x {d_k} dims). "
|
|
53
|
+
"Cache ports show K/V write/read during generation: arrowhead for write, blunt tail for read."
|
|
54
|
+
),
|
|
52
55
|
},
|
|
53
56
|
{
|
|
54
57
|
"id": "v_proj",
|
|
55
58
|
"title": "Value projection",
|
|
56
|
-
"description":
|
|
59
|
+
"description": (
|
|
60
|
+
f"Linear; {hidden} -> {kv_out} ({num_kv_heads} KV-heads x {d_k} dims). "
|
|
61
|
+
"Cache ports show K/V write/read during generation: arrowhead for write, blunt tail for read."
|
|
62
|
+
),
|
|
57
63
|
},
|
|
58
64
|
{
|
|
59
65
|
"id": "qkv_dot",
|
|
@@ -104,12 +110,18 @@ def _sdpa_detailed_child_blocks(
|
|
|
104
110
|
{
|
|
105
111
|
"id": "k_proj",
|
|
106
112
|
"title": "Key projection",
|
|
107
|
-
"description":
|
|
113
|
+
"description": (
|
|
114
|
+
f"Linear; {hidden} -> {kv_out} ({kv_label} x {d_k} dims). "
|
|
115
|
+
"Cache ports show K/V write/read during generation: arrowhead for write, blunt tail for read."
|
|
116
|
+
),
|
|
108
117
|
},
|
|
109
118
|
{
|
|
110
119
|
"id": "v_proj",
|
|
111
120
|
"title": "Value projection",
|
|
112
|
-
"description":
|
|
121
|
+
"description": (
|
|
122
|
+
f"Linear; {hidden} -> {kv_out} ({kv_label} x {d_k} dims). "
|
|
123
|
+
"Cache ports show K/V write/read during generation: arrowhead for write, blunt tail for read."
|
|
124
|
+
),
|
|
113
125
|
},
|
|
114
126
|
{
|
|
115
127
|
"id": "scaled_scores",
|
|
@@ -232,7 +244,10 @@ def _mla_child_blocks(attention: AttentionSpec, hidden_size: int) -> list[dict]:
|
|
|
232
244
|
"id": "mla_cache",
|
|
233
245
|
"label": "latent cache c_t",
|
|
234
246
|
"title": "Stored latent cache",
|
|
235
|
-
"description":
|
|
247
|
+
"description": (
|
|
248
|
+
f"Compressed K/V latent stored in the cache instead of full K and V heads; rank {kv_rank}. "
|
|
249
|
+
"Cache ports show write from compression and read back into K/V expansion."
|
|
250
|
+
),
|
|
236
251
|
},
|
|
237
252
|
{
|
|
238
253
|
"id": "mla_kv_up",
|
|
@@ -289,7 +304,7 @@ def _mla_child_blocks(attention: AttentionSpec, hidden_size: int) -> list[dict]:
|
|
|
289
304
|
"title": "MLA K/V cache path",
|
|
290
305
|
"description": (
|
|
291
306
|
f"Compresses hidden state into rank {kv_rank} latent cache, expands K/V content, "
|
|
292
|
-
"and combines K noPE with a RoPE key side-channel"
|
|
307
|
+
"and combines K noPE with a RoPE key side-channel. Cache ports mark the latent write/read point."
|
|
293
308
|
),
|
|
294
309
|
"detail_view": "mla_kv_cache_path",
|
|
295
310
|
"children": kv_children,
|
|
@@ -67,13 +67,14 @@ def describe_attention(attention: AttentionSpec) -> str:
|
|
|
67
67
|
)
|
|
68
68
|
if attention.q_lora_rank:
|
|
69
69
|
text += f"; Q LoRA {_fmt(attention.q_lora_rank)}"
|
|
70
|
+
text += "; cache ports mark latent write/read state"
|
|
70
71
|
return text
|
|
71
72
|
if attention.kind == "mqa":
|
|
72
|
-
return _with_attention_window(attention, f"Multi-query; {attention.num_heads} Q / 1 KV head")
|
|
73
|
+
return _with_attention_window(attention, f"Multi-query; {attention.num_heads} Q / 1 KV head; cache ports mark K/V write/read state")
|
|
73
74
|
if attention.kind == "gqa":
|
|
74
75
|
return _with_attention_window(attention, (
|
|
75
76
|
f"Grouped-query; {attention.num_heads} Q / {attention.num_kv_heads} KV heads; "
|
|
76
|
-
f"head dim {_fmt(attention.head_dim)}"
|
|
77
|
+
f"head dim {_fmt(attention.head_dim)}; cache ports mark K/V write/read state"
|
|
77
78
|
))
|
|
78
79
|
if attention.kind == "ssm":
|
|
79
80
|
shared = "; weight-shared across positions" if attention.shared else ""
|
|
@@ -94,11 +95,12 @@ def describe_attention(attention: AttentionSpec) -> str:
|
|
|
94
95
|
if attention.no_rope:
|
|
95
96
|
extras.append("NoPE")
|
|
96
97
|
suffix = f"; {', '.join(extras)}" if extras else ""
|
|
97
|
-
|
|
98
|
+
cache_note = "; cache ports mark K/V write/read state"
|
|
99
|
+
return _with_attention_window(attention, f"Multi-head; {attention.num_heads} heads; head dim {_fmt(attention.head_dim)}{suffix}{cache_note}")
|
|
98
100
|
|
|
99
101
|
|
|
100
102
|
def _attention_mask_prefix(attention: AttentionSpec) -> str:
|
|
101
|
-
return "
|
|
103
|
+
return "SW" if attention.mask == "sliding" else ""
|
|
102
104
|
|
|
103
105
|
|
|
104
106
|
def _attention_mask_title_prefix(attention: AttentionSpec) -> str:
|