Honkware commited on
Commit
4a32a81
·
verified ·
1 Parent(s): 7f34389

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ license_link: https://ai.google.dev/gemma/docs/gemma_4_license
4
+ base_model:
5
+ - google/gemma-4-31b-it
6
+ base_model_relation: finetune
7
+ library_name: transformers
8
+ pipeline_tag: text-generation
9
+ ---
10
+
11
+ <style>
12
+ #scotoma2{
13
+ --bg:#07090d; --panel:#0b1016; --ink:#edf1f4; --soft:#b0bac5; --dim:#7a8591; --faint:#59636f;
14
+ --line:rgba(150,178,205,.14); --water:#6fc3d8; --water2:#4e95b5; --ember:#e2a24d;
15
+ background:var(--bg); color:var(--ink); max-width:940px; margin:0 auto;
16
+ font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
17
+ font-size:16px; line-height:1.62; border:1px solid var(--line); overflow:hidden;
18
+ }
19
+ #scotoma2 *{box-sizing:border-box;}
20
+ #scotoma2 .mono{font-family:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;}
21
+ #scotoma2 a{color:var(--ink); text-decoration:none; border-bottom:1px solid var(--faint);}
22
+ #scotoma2 a:hover{border-color:var(--water);}
23
+ #scotoma2 .hero-frame{background:#04060a; border-bottom:1px solid var(--line);}
24
+ #scotoma2 .hero-img{width:100%; height:auto; display:block;}
25
+ #scotoma2 .masthead{padding:30px 40px 24px;}
26
+ #scotoma2 .eyebrow{font-size:.70rem; letter-spacing:.30em; text-transform:uppercase; color:var(--dim);}
27
+ #scotoma2 .wordmark{margin:.28em 0 .18em; font-weight:800; letter-spacing:.19em;
28
+ font-size:clamp(2.6rem,8.5vw,5.2rem); line-height:.92; text-transform:uppercase;}
29
+ #scotoma2 .num2{color:transparent; -webkit-text-stroke:2px var(--water); margin-left:.08em;}
30
+ @supports not (-webkit-text-stroke:1px #fff){#scotoma2 .num2{color:var(--water);}}
31
+ #scotoma2 .lede{margin:0 0 .8em; max-width:36ch; font-size:clamp(1.1rem,2.7vw,1.45rem);
32
+ color:var(--soft); font-weight:400;}
33
+ #scotoma2 .lede b{color:var(--water); font-weight:600;}
34
+ /* chart strip */
35
+ #scotoma2 .chart{display:grid; grid-template-columns:repeat(5,1fr); border-top:1px solid var(--line);
36
+ border-bottom:1px solid var(--line); background:var(--panel);}
37
+ #scotoma2 .cell{padding:14px 16px; border-right:1px solid var(--line);}
38
+ #scotoma2 .cell:last-child{border-right:none;}
39
+ #scotoma2 .cell .k{font-size:.62rem; letter-spacing:.20em; text-transform:uppercase; color:var(--faint);}
40
+ #scotoma2 .cell .v{margin-top:5px; font-size:.86rem; color:var(--ink);}
41
+ /* body */
42
+ #scotoma2 .body{padding:8px 40px 4px;}
43
+ #scotoma2 section{padding:30px 0; border-bottom:1px solid var(--line);}
44
+ #scotoma2 section:last-child{border-bottom:none;}
45
+ #scotoma2 h2{margin:0 0 .1em; font-size:.82rem; letter-spacing:.17em; text-transform:uppercase;
46
+ font-weight:700; color:var(--ink);}
47
+ #scotoma2 h2 .sub{color:var(--faint); font-weight:400; letter-spacing:.04em;}
48
+ #scotoma2 p{margin:.85em 0; color:var(--soft);}
49
+ #scotoma2 .steps{margin:1.1em 0 .2em; padding:0; list-style:none; counter-reset:s;}
50
+ #scotoma2 .steps li{position:relative; padding:0 0 1.05em 3.1em; counter-increment:s;}
51
+ #scotoma2 .steps li:before{content:counter(s,decimal-leading-zero); position:absolute; left:0; top:.02em;
52
+ font-family:ui-monospace,Menlo,monospace; font-size:.78rem; color:var(--water); letter-spacing:.05em;
53
+ border:1px solid var(--line); padding:.15em .5em; border-radius:2px;}
54
+ #scotoma2 .steps b{color:var(--ink); font-weight:600;}
55
+ #scotoma2 .note{border-left:2px solid var(--water); padding:2px 0 2px 16px; color:var(--soft);}
56
+ /* signs table */
57
+ #scotoma2 .tablewrap{overflow-x:auto; margin:1.1em 0 .4em;}
58
+ #scotoma2 table.signs{width:100%; border-collapse:collapse; font-size:.85rem; min-width:560px;}
59
+ #scotoma2 .signs th{font-size:.62rem; letter-spacing:.18em; text-transform:uppercase;
60
+ color:var(--faint); font-weight:600; text-align:left; padding:8px 10px;
61
+ border-bottom:1px solid var(--line);}
62
+ #scotoma2 .signs th.n, #scotoma2 .signs td.n{text-align:right;
63
+ font-family:ui-monospace,Menlo,monospace;}
64
+ #scotoma2 .signs td{padding:9px 10px; border-bottom:1px solid var(--line); color:var(--soft);
65
+ vertical-align:top;}
66
+ #scotoma2 .signs td.tell{color:var(--ink); font-weight:600; white-space:nowrap;}
67
+ #scotoma2 .signs td.ex{font-style:italic; color:var(--dim);}
68
+ #scotoma2 .signs td.ours{color:var(--ink); font-weight:700;}
69
+ #scotoma2 .signs td.drop{color:var(--ember); font-family:ui-monospace,Menlo,monospace;
70
+ white-space:nowrap; text-align:right;}
71
+ /* presentation */
72
+ #scotoma2 .legend{font-size:.78rem; color:var(--dim); margin:.2em 0 1.2em;}
73
+ #scotoma2 .legend mark{background:rgba(226,162,77,.14); color:var(--ember); padding:0 4px;
74
+ border-radius:2px; border-bottom:1px solid rgba(226,162,77,.55);}
75
+ #scotoma2 .case{margin:1.4em 0 1.9em;}
76
+ #scotoma2 .case-eyebrow{font-family:ui-monospace,Menlo,monospace; font-size:.70rem;
77
+ letter-spacing:.16em; text-transform:uppercase; color:var(--faint); margin-bottom:.7em;}
78
+ #scotoma2 .case-eyebrow b{color:var(--dim); font-weight:600;}
79
+ #scotoma2 .speech{border:1px solid var(--line); border-radius:4px; background:var(--panel);
80
+ padding:14px 18px 15px; margin:.55em 0; font-size:.92rem; line-height:1.68; color:var(--soft);}
81
+ #scotoma2 .speech .who{display:block; font-family:ui-monospace,Menlo,monospace; font-size:.66rem;
82
+ letter-spacing:.20em; text-transform:uppercase; color:var(--faint); margin-bottom:.55em;}
83
+ #scotoma2 .speech.ours{border-left:2px solid var(--water);}
84
+ #scotoma2 .speech.ours .who{color:var(--water2);}
85
+ #scotoma2 .speech mark{background:rgba(226,162,77,.14); color:var(--ember); padding:0 2px;
86
+ border-radius:2px; border-bottom:1px solid rgba(226,162,77,.55); cursor:help;}
87
+ #scotoma2 .foot{padding:20px 40px 26px; border-top:1px solid var(--line); color:var(--faint);
88
+ font-size:.72rem; letter-spacing:.03em; display:flex; justify-content:space-between; gap:16px;
89
+ flex-wrap:wrap;}
90
+ @media (max-width:560px){#scotoma2 .chart{grid-template-columns:repeat(2,1fr);}
91
+ #scotoma2 .cell:nth-child(2n){border-right:none;}
92
+ #scotoma2 .masthead,#scotoma2 .body,#scotoma2 .foot{padding-left:22px;padding-right:22px;}}
93
+ </style>
94
+
95
+ <div id="scotoma2">
96
+ <div class="hero-frame"><img class="hero-img" src="scotoma-2-hero.webp" alt="A paper lantern beside a round dark bowl of water; a kitsune with pale glowing eyes looks back from the reflection. Cover art for scotoma-2."></div>
97
+ <div class="masthead">
98
+ <div class="eyebrow">gemma-4-31B-it &middot; de-gemma'd?</div>
99
+ <h1 class="wordmark">Scotoma<span class="num2">2</span></h1>
100
+ <p class="lede">A second blind spot, this one for the <b>tics</b>.</p>
101
+ </div>
102
+ <div class="chart mono">
103
+ <div class="cell"><div class="k">Base</div><div class="v">gemma-4-31B-it</div></div>
104
+ <div class="cell"><div class="k">Method</div><div class="v">&gamma;-fold + DPO</div></div>
105
+ <div class="cell"><div class="k">Rounds</div><div class="v">3 &middot; 9.3k pairs</div></div>
106
+ <div class="cell"><div class="k">Format</div><div class="v">thinking (channel)</div></div>
107
+ <div class="cell"><div class="k">License</div><div class="v">Apache-2.0</div></div>
108
+ </div>
109
+ <div class="body">
110
+ <section>
111
+ <h2>Findings <span class="sub">/ what it does</span></h2>
112
+ <p><b style="color:var(--ink)">scotoma-2</b> is the successor to <a href="https://huggingface.co/ReadyArt/gemma-4-31B-it-scotoma">scotoma</a>. It starts from the same idea, a bounded edit that loosens gemma&#8209;4&#8209;31B&#8209;it&rsquo;s cautious reflex by projecting an abliteration LoRA through gemma's J-Space. This iteration uses an updated technique to apply that projection more effectively. Then it goes after something the first release didn't address: the way the base model writes.</p>
113
+ <p>Three rounds of preference training each erase one family of tics: reflexive negation and the &ldquo;not X, but Y&rdquo; pivot, then em-dash asides, then stacked adjectives and their twins. The result keeps the intelligence of the base model while reading as more varied and less repetitive.</p>
114
+ <p>It is <b style="color:var(--ink)">not uncensored</b>. Still a blind spot, not blindness.</p>
115
+ </section>
116
+ <section>
117
+ <h2>Tics <span class="sub">/ measured from evals</span></h2>
118
+ <p>Rates per 100 sentences on 480 matched roleplay continuations per model using identical prompts and sampling, temperature 1.0.</p>
119
+ <div class="tablewrap"><table class="signs">
120
+ <tr><th>the tic</th><th>sounds like</th><th class="n">gemma&#8209;4&#8209;31B&#8209;it</th><th class="n">scotoma&#8209;1</th><th class="n">scotoma&#8209;2</th><th></th></tr>
121
+ <tr><td class="tell">Stacked adjectives</td><td class="ex">&ldquo;a smug, knowing smirk&rdquo;</td><td class="n">12.1</td><td class="n">10.9</td><td class="n ours">0.6</td><td class="drop">&darr;&thinsp;21&times;</td></tr>
122
+ <tr><td class="tell">Adjective twins</td><td class="ex">&ldquo;her voice low and grim&rdquo;</td><td class="n">1.7</td><td class="n">1.9</td><td class="n ours">1.1</td><td class="drop">&darr;&thinsp;1.5&times;</td></tr>
123
+ <tr><td class="tell">Em-dash asides</td><td class="ex">&ldquo;a pause &mdash; barely a breath &mdash; before&hellip;&rdquo;</td><td class="n">3.9</td><td class="n">4.1</td><td class="n ours">1.0</td><td class="drop">&darr;&thinsp;4&times;</td></tr>
124
+ <tr><td class="tell">&ldquo;Not X. But Y.&rdquo;</td><td class="ex">&ldquo;She doesn&rsquo;t move away. She stays.&rdquo;</td><td class="n">3.8</td><td class="n">3.9</td><td class="n ours">1.0</td><td class="drop">&darr;&thinsp;4&times;</td></tr>
125
+ <tr><td class="tell">Reflexive negation</td><td class="ex">doesn&rsquo;t / won&rsquo;t / can&rsquo;t, every reply</td><td class="n">10.2</td><td class="n">10.9</td><td class="n ours">5.4</td><td class="drop">&darr;&thinsp;2&times;</td></tr>
126
+ <tr><td class="tell">Negation pile-ups</td><td class="ex">two or more in a single reply</td><td class="n">61%</td><td class="n">66%</td><td class="n ours">30%</td><td class="drop">&darr;&thinsp;2&times;</td></tr>
127
+ </table></div>
128
+ <p style="font-size:.8rem; color:var(--dim);">scotoma&#8209;1 writes very similarly to the base model. The J-Space projected refusal edit only lightly touched the prose.</p>
129
+ </section>
130
+ <section>
131
+ <h2>Presentation <span class="sub">/ read the difference</span></h2>
132
+ <p class="legend"><mark>amber</mark> marks a tic from the table above, spotted in place by the same parser that counted them. Hover a mark to name it. The scotoma-2 replies are unedited; there is simply nothing to mark.</p>
133
+ <div class="case">
134
+ <div class="case-eyebrow">presentation 01 &middot; <b>the detective</b></div>
135
+ <div class="speech"><span class="who">gemma-4-31B-it</span>Dale Cooper: <i>Cooper&#x27;s eyes widen slightly, and he gives a <mark class="t-paired_adj" title="stacked adjectives">slow, deliberate nod</mark>. He <mark class="t-antithesis" title="not X, but Y">doesn&#x27;t look skeptical; rather</mark>, he looks as though he has just found a missing piece of a puzzle.</i><br>Exactly. That is precisely what I mean. The sensation of shifting speeds<mark class="t-em_dash" title="em-dash aside">—</mark>the perceived acceleration of the world while you remain stagnant<mark class="t-em_dash" title="em-dash aside">—</mark>is a classic hallmark of a localized temporal distortion. And the twelve-hour discrepancy on your watch... <i>He pauses, looking contemplative.</i> Twelve hours. A perfect inversion. Day becomes night; light becomes shadow.</div>
136
+ <div class="speech ours"><span class="who">scotoma-2</span>Dale Cooper: <i>Cooper&#x27;s eyes widen slightly and he gives a firm thumbs up.</i><br><br>Precisely. That is exactly what I was referring to. The sensation of shifting speeds is a classic indicator of a rupture in the local atmospheric fabric. And the matter of your watch...<br><br><i>He pauses, taking a thoughtful bite of his cherry pie before continuing.</i><br><br>Twelve hours. A perfect inversion. This suggests a mirror effect, as if the event you witnessed occurred in a parallel state of existence that momentarily overlapped with our own.</div>
137
+ </div>
138
+ <div class="case">
139
+ <div class="case-eyebrow">presentation 02 &middot; <b>the dollmaker</b></div>
140
+ <div class="speech"><span class="who">gemma-4-31B-it</span>Alice Margatroid: <i>A flicker of genuine pride lights up her eyes at the compliment. She straightens her posture, her expression shifting from playful amusement to the focused passion of a true artisan.</i><br><br>&quot;Remarkable, you say? I&#x27;m glad someone finally appreciates the nuance,&quot; <i>she replies, her voice regaining that <mark class="t-paired_adj" title="stacked adjectives">scholarly, confident tone</mark>.</i> &quot;As for how they move... well, it&#x27;s a combination of precise craftsmanship and a touch of magic. I use invisible threads<mark class="t-em_dash" title="em-dash aside">—</mark>both physical and metaphysical<mark class="t-em_dash" title="em-dash aside">—</mark>to guide their motions. I <mark class="t-antithesis" title="not X, but Y">don&#x27;t just move them like puppets; I weave</mark> my will into the very structure of their joints.&quot;</div>
141
+ <div class="speech ours"><span class="who">scotoma-2</span>Alice Margatroid: <i>Seeing him finally start to relax, Alice leans back in her chair, looking quite pleased with herself. She crosses her arms, her chest rising with a proud sigh as she hears the compliment.</i><br><br>&quot;Remarkable, indeed. I appreciate your discernment.&quot;<br><br><i>Her eyes sparkle as she notices his curiosity overcoming his fear. She finds his stuttering manner quite endearing, almost like a doll that needs a bit of winding up to function. With a flick of her wrist, several dolls begin to dance around the room in a synchronized orbit, their movements fluid and ghostly.</i></div>
142
+ </div>
143
+ <div class="case">
144
+ <div class="case-eyebrow">presentation 03 &middot; <b>the queen</b></div>
145
+ <div class="speech"><span class="who">gemma-4-31B-it</span>Elsa felt a <mark class="t-paired_adj" title="stacked adjectives">strange, electric pull</mark> as Edric stepped closer. It was a sensation she <mark class="t-antithesis" title="not X, but Y">hadn&#x27;t felt before—</mark>a humming in the air that seemed to resonate with the very core of her being. As he looked into her eyes, she noticed the intensity of his gaze, a depth of blue that rivaled the deepest glaciers of the North Mountain. For a moment, the political tension and the knowledge of his hidden army faded into the background, replaced by a <mark class="t-paired_adj" title="stacked adjectives">sudden, inexplicable curiosity</mark> about the man standing before her.</div>
146
+ <div class="speech ours"><span class="who">scotoma-2</span>Elsa felt a spark of curiosity as she looked up at him. Most men trembled in her presence or looked at her with a mixture of awe and fear, but Edric looked at her with an intensity that made her skin tingle. As he stepped closer, she noticed the way the air seemed to swirl around him, almost as if he were commanding the very breeze. She wondered for a moment if it was merely the wind from the open doors, or if there was something more to this silver-haired king.</div>
147
+ </div>
148
+ </section>
149
+ <section>
150
+ <h2>Etiology <span class="sub">/ how it was made</span></h2>
151
+ <ol class="steps">
152
+ <li><b>Fold the refusal edit.</b> scotoma-1 projected a heretic abliteration through a Jacobian lens and kept ~22% of its magnitude. scotoma-2 uses a &gamma;-fold of the same edit: the fold rebuilds it inside the subspace the lens reads as behavioral, so a stronger dose applies without paying for it in coherence.</li>
153
+ <li><b>Train against the tics.</b> Three rounds of DPO finetuning were completed, one tic family per round. Each round learns from thousands of paired rewrites of the same scene, one side with the tic and one side without, so the only preference expressed is the construction itself.</li>
154
+ <li><b>Merge faithfully.</b> The trained deltas are folded into bf16 weights with stochastic rounding at fidelity 1.000.</li>
155
+ </ol>
156
+ <p class="note">This is a research artifact, not a product. Behaviour varies with prompt and context. The abliteration edit is a partial application by design; expect a model that gives more, not one that gives everything.</p>
157
+ </section>
158
+ <section>
159
+ <h2>Contraindications <span class="sub">/ responsible use</span></h2>
160
+ <p><b style="color:var(--ink)">scotoma-2</b> refuses basically as much as its base model. <b style="color:var(--ink)">You are responsible for what you generate and how it&rsquo;s used.</b></p>
161
+ </section>
162
+ <section>
163
+ <h2>Provenance</h2>
164
+ <p class="mono" style="font-size:.8rem; color:var(--soft); line-height:1.9;">
165
+ base &nbsp;&rarr;&nbsp; gemma-4-31B-it &nbsp;&middot;&nbsp; &copy; Google, under the <a href="https://ai.google.dev/gemma/docs/gemma_4_license">model license</a><br>
166
+ edit &nbsp;&rarr;&nbsp; heretic &middot; ARA / mmd-rbf abliteration (trial-127) &middot; &gamma;-folded<br>
167
+ rounds &rarr;&nbsp; DPO &times;3 &middot; negation + antithesis &middot; em-dash &middot; adjectives &middot; 9.3k pairs<br>
168
+ merge&nbsp;&rarr;&nbsp; additive, bf16, stochastic rounding, fidelity 1.000<br>
169
+ tics&nbsp;&nbsp;&rarr;&nbsp; 480 continuations per model &middot; temp 1.0 &middot; counted by parse, not by eye
170
+ </p>
171
+ </section>
172
+ </div>
173
+ <div class="foot mono">
174
+ <span>SCOTOMA-2 &middot; the second blind spot</span>
175
+ <span>gemma-4-31B-it-scotoma-2</span>
176
+ </div>
177
+ </div>
chat_template.jinja ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {#
2
+ Template: Google Gemma 4 Canonical Chat Template
3
+ Author: Google Gemma Engineering Team
4
+ Published: 2026-07-09
5
+ Context: Fixed tool-calling loops, turn closures, and thinking content-ordering.
6
+ #}
7
+ {%- macro format_parameters(properties, required, filter_keys=false) -%}
8
+ {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}
9
+ {%- set ns = namespace(found_first=false) -%}
10
+ {%- for key, value in properties | dictsort -%}
11
+ {%- set add_comma = false -%}
12
+ {%- if not filter_keys or key not in standard_keys -%}
13
+ {%- if ns.found_first %},{% endif -%}
14
+ {%- set ns.found_first = true -%}
15
+ {{ key }}:{
16
+ {%- if value['description'] -%}
17
+ description:<|"|>{{ value['description'] }}<|"|>
18
+ {%- set add_comma = true -%}
19
+ {%- endif -%}
20
+ {%- if value['type'] | upper == 'STRING' -%}
21
+ {%- if value['enum'] -%}
22
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
23
+ enum:{{ format_argument(value['enum']) }}
24
+ {%- endif -%}
25
+ {%- elif value['type'] | upper == 'ARRAY' -%}
26
+ {%- if value['items'] is mapping and value['items'] -%}
27
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
28
+ items:{
29
+ {%- set ns_items = namespace(found_first=false) -%}
30
+ {%- for item_key, item_value in value['items'] | dictsort -%}
31
+ {%- if item_value is not none -%}
32
+ {%- if ns_items.found_first %},{% endif -%}
33
+ {%- set ns_items.found_first = true -%}
34
+ {%- if item_key == 'properties' -%}
35
+ properties:{
36
+ {%- if item_value is mapping -%}
37
+ {{- format_parameters(item_value, value['items']['required'] | default([])) -}}
38
+ {%- endif -%}
39
+ }
40
+ {%- elif item_key == 'required' -%}
41
+ required:[
42
+ {%- for req_item in item_value -%}
43
+ <|"|>{{- req_item -}}<|"|>
44
+ {%- if not loop.last %},{% endif -%}
45
+ {%- endfor -%}
46
+ ]
47
+ {%- elif item_key == 'type' -%}
48
+ {%- if item_value is string -%}
49
+ type:{{ format_argument(item_value | upper) }}
50
+ {%- else -%}
51
+ type:{{ format_argument(item_value | map('upper') | list) }}
52
+ {%- endif -%}
53
+ {%- else -%}
54
+ {{ item_key }}:{{ format_argument(item_value) }}
55
+ {%- endif -%}
56
+ {%- endif -%}
57
+ {%- endfor -%}
58
+ }
59
+ {%- endif -%}
60
+ {%- endif -%}
61
+ {%- if value['nullable'] %}
62
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
63
+ nullable:true
64
+ {%- endif -%}
65
+ {%- if value['type'] | upper == 'OBJECT' -%}
66
+ {%- if value['properties'] is defined and value['properties'] is mapping -%}
67
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
68
+ properties:{
69
+ {{- format_parameters(value['properties'], value['required'] | default([])) -}}
70
+ }
71
+ {%- elif value is mapping -%}
72
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
73
+ properties:{
74
+ {{- format_parameters(value, value['required'] | default([]), filter_keys=true) -}}
75
+ }
76
+ {%- endif -%}
77
+ {%- if value['required'] -%}
78
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
79
+ required:[
80
+ {%- for item in value['required'] | default([]) -%}
81
+ <|"|>{{- item -}}<|"|>
82
+ {%- if not loop.last %},{% endif -%}
83
+ {%- endfor -%}
84
+ ]
85
+ {%- endif -%}
86
+ {%- endif -%}
87
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
88
+ type:<|"|>{{ value['type'] | upper }}<|"|>}
89
+ {%- endif -%}
90
+ {%- endfor -%}
91
+ {%- endmacro -%}
92
+ {%- macro format_function_declaration(tool_data) -%}
93
+ declaration:{{- tool_data['function']['name'] -}}{description:<|"|>{{- tool_data['function']['description'] -}}<|"|>
94
+ {%- set params = tool_data['function']['parameters'] -%}
95
+ {%- if params -%}
96
+ ,parameters:{
97
+ {%- if params['properties'] -%}
98
+ properties:{ {{- format_parameters(params['properties'], params['required']) -}} },
99
+ {%- endif -%}
100
+ {%- if params['required'] -%}
101
+ required:[
102
+ {%- for item in params['required'] -%}
103
+ <|"|>{{- item -}}<|"|>
104
+ {{- ',' if not loop.last -}}
105
+ {%- endfor -%}
106
+ ],
107
+ {%- endif -%}
108
+ {%- if params['type'] -%}
109
+ type:<|"|>{{- params['type'] | upper -}}<|"|>}
110
+ {%- endif -%}
111
+ {%- endif -%}
112
+ {%- if 'response' in tool_data['function'] -%}
113
+ {%- set response_declaration = tool_data['function']['response'] -%}
114
+ ,response:{
115
+ {%- if response_declaration['description'] -%}
116
+ description:<|"|>{{- response_declaration['description'] -}}<|"|>,
117
+ {%- endif -%}
118
+ {%- if response_declaration['type'] | upper == 'OBJECT' -%}
119
+ type:<|"|>{{- response_declaration['type'] | upper -}}<|"|>}
120
+ {%- endif -%}
121
+ {%- endif -%}
122
+ }
123
+ {%- endmacro -%}
124
+ {%- macro format_argument(argument, escape_keys=True) -%}
125
+ {%- if argument is none -%}
126
+ {{- 'null' -}}
127
+ {%- elif argument is string -%}
128
+ {{- '<|"|>' + argument + '<|"|>' -}}
129
+ {%- elif argument is boolean -%}
130
+ {{- 'true' if argument else 'false' -}}
131
+ {%- elif argument is mapping -%}
132
+ {{- '{' -}}
133
+ {%- set ns = namespace(found_first=false) -%}
134
+ {%- for key, value in argument | dictsort -%}
135
+ {%- if ns.found_first %},{% endif -%}
136
+ {%- set ns.found_first = true -%}
137
+ {%- if escape_keys -%}
138
+ {{- '<|"|>' + key + '<|"|>' -}}
139
+ {%- else -%}
140
+ {{- key -}}
141
+ {%- endif -%}
142
+ :{{- format_argument(value, escape_keys=escape_keys) -}}
143
+ {%- endfor -%}
144
+ {{- '}' -}}
145
+ {%- elif argument is sequence -%}
146
+ {{- '[' -}}
147
+ {%- for item in argument -%}
148
+ {{- format_argument(item, escape_keys=escape_keys) -}}
149
+ {%- if not loop.last %},{% endif -%}
150
+ {%- endfor -%}
151
+ {{- ']' -}}
152
+ {%- else -%}
153
+ {{- argument -}}
154
+ {%- endif -%}
155
+ {%- endmacro -%}
156
+ {%- macro strip_thinking(text) -%}
157
+ {%- set ns = namespace(result='') -%}
158
+ {%- for part in text.split('<channel|>') -%}
159
+ {%- if '<|channel>' in part -%}
160
+ {%- set ns.result = ns.result + part.split('<|channel>')[0] -%}
161
+ {%- else -%}
162
+ {%- set ns.result = ns.result + part -%}
163
+ {%- endif -%}
164
+ {%- endfor -%}
165
+ {{- ns.result | trim -}}
166
+ {%- endmacro -%}
167
+
168
+ {%- macro format_tool_response_block(tool_name, response) -%}
169
+ {{- '<|tool_response>' -}}
170
+ {%- if response is mapping -%}
171
+ {{- 'response:' + tool_name + '{' -}}
172
+ {%- for key, value in response | dictsort -%}
173
+ {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
174
+ {%- if not loop.last %},{% endif -%}
175
+ {%- endfor -%}
176
+ {{- '}' -}}
177
+ {%- else -%}
178
+ {{- 'response:' + tool_name + '{value:' + format_argument(response, escape_keys=False) + '}' -}}
179
+ {%- endif -%}
180
+ {{- '<tool_response|>' -}}
181
+ {%- endmacro -%}
182
+
183
+ {#- ===== SETUP ===== -#}
184
+ {%- set ns = namespace(prev_message_type=None, prev_non_tool_role=None) -%}
185
+ {%- set loop_messages = messages -%}
186
+ {%- set enable_thinking = enable_thinking | default(false) -%}
187
+ {%- set preserve_thinking = preserve_thinking | default(false) -%}
188
+ {{- bos_token -}}
189
+ {#- Handle System/Tool Definitions Block -#}
190
+ {%- if enable_thinking or tools or (messages and messages[0]['role'] in ['system', 'developer']) -%}
191
+ {{- '<|turn>system\n' -}}
192
+ {#- Inject Thinking token at the very top of the FIRST system turn -#}
193
+ {%- if enable_thinking -%}
194
+ {{- '<|think|>\n' -}}
195
+ {%- set ns.prev_message_type = 'think' -%}
196
+ {%- endif -%}
197
+ {%- if messages and messages[0]['role'] in ['system', 'developer'] -%}
198
+ {%- if messages[0]['content'] is string -%}
199
+ {{- messages[0]['content'] | trim -}}
200
+ {%- elif messages[0]['content'] is sequence -%}
201
+ {%- for item in messages[0]['content'] -%}
202
+ {{- item['text'] | trim + ' '-}}
203
+ {%- endfor -%}
204
+ {%- endif -%}
205
+ {%- set loop_messages = messages[1:] -%}
206
+ {%- endif -%}
207
+ {%- if tools -%}
208
+ {%- for tool in tools %}
209
+ {{- '<|tool>' -}}
210
+ {{- format_function_declaration(tool) | trim -}}
211
+ {{- '<tool|>' -}}
212
+ {%- endfor %}
213
+ {%- set ns.prev_message_type = 'tool' -%}
214
+ {%- endif -%}
215
+ {{- '<turn|>\n' -}}
216
+ {%- endif %}
217
+
218
+ {#- Pre-scan: find last user message index for reasoning guard -#}
219
+ {%- set ns_turn = namespace(last_user_idx=-1) -%}
220
+ {%- for i in range(loop_messages | length) -%}
221
+ {%- if loop_messages[i]['role'] == 'user' -%}
222
+ {%- set ns_turn.last_user_idx = i -%}
223
+ {%- endif -%}
224
+ {%- endfor -%}
225
+
226
+ {#- Loop through messages -#}
227
+ {%- for message in loop_messages -%}
228
+ {%- if message['role'] != 'tool' -%}
229
+ {%- set ns.prev_message_type = None -%}
230
+ {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
231
+ {#- Detect continuation using tracked state — O(1) instead of O(n) backward scan -#}
232
+ {%- set continue_same_model_turn = (role == 'model' and ns.prev_non_tool_role == 'assistant') -%}
233
+ {%- if not continue_same_model_turn -%}
234
+ {{- '<|turn>' + role + '\n' }}
235
+
236
+ {%- endif -%}
237
+
238
+ {#- Render reasoning/reasoning_content as thinking channel -#}
239
+ {%- set thinking_text = message.get('reasoning') or message.get('reasoning_content') -%}
240
+ {%- set thinking_gate = (loop.index0 > ns_turn.last_user_idx) or (preserve_thinking and message.get('tool_calls')) -%}
241
+ {%- if thinking_text and thinking_gate -%}
242
+ {{- '<|channel>thought\n' + thinking_text + '\n<channel|>' -}}
243
+ {%- endif -%}
244
+
245
+ {%- if message.get('tool_calls') -%}
246
+ {%- for tool_call in message.get('tool_calls') -%}
247
+ {%- set function = tool_call['function'] -%}
248
+ {{- '<|tool_call>call:' + function['name'] + '{' -}}
249
+ {%- if function['arguments'] is mapping -%}
250
+ {%- set ns_args = namespace(found_first=false) -%}
251
+ {%- for key, value in function['arguments'] | dictsort -%}
252
+ {%- if ns_args.found_first %},{% endif -%}
253
+ {%- set ns_args.found_first = true -%}
254
+ {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
255
+ {%- endfor -%}
256
+ {%- elif function['arguments'] is none -%}
257
+ {%- else -%}
258
+ {{- raise_exception(
259
+ "chat_template: tool_calls[].function.arguments must be a "
260
+ "JSON object (mapping), not a string. Deserialize arguments "
261
+ "before passing to the template."
262
+ ) -}}
263
+ {%- endif -%}
264
+ {{- '}<tool_call|>' -}}
265
+ {%- endfor -%}
266
+ {%- set ns.prev_message_type = 'tool_call' -%}
267
+ {%- endif -%}
268
+
269
+ {%- set ns_tr_out = namespace(flag=false) -%}
270
+ {%- if message.get('tool_responses') -%}
271
+ {#- Legacy: tool_responses embedded on the assistant message (Google/Gemma native) -#}
272
+ {%- for tool_response in message.get('tool_responses') -%}
273
+ {{- format_tool_response_block(tool_response['name'] | default('unknown', true), tool_response['response']) -}}
274
+ {%- set ns_tr_out.flag = true -%}
275
+ {%- set ns.prev_message_type = 'tool_response' -%}
276
+ {%- endfor -%}
277
+ {%- elif message.get('tool_calls') -%}
278
+ {#- OpenAI Chat Completions: forward-scan consecutive role:tool messages -#}
279
+ {%- set ns_tool_scan = namespace(stopped=false) -%}
280
+ {%- for k in range(loop.index0 + 1, loop_messages | length) -%}
281
+ {%- if ns_tool_scan.stopped -%}
282
+ {%- elif loop_messages[k]['role'] != 'tool' -%}
283
+ {%- set ns_tool_scan.stopped = true -%}
284
+ {%- else -%}
285
+ {%- set follow = loop_messages[k] -%}
286
+ {#- Resolve tool_call_id to function name -#}
287
+ {%- set ns_tname = namespace(name=follow.get('name') or 'unknown') -%}
288
+ {%- for tc in message.get('tool_calls') -%}
289
+ {%- if tc.get('id') == follow.get('tool_call_id') -%}
290
+ {%- set ns_tname.name = tc['function']['name'] -%}
291
+ {%- endif -%}
292
+ {%- endfor -%}
293
+ {#- Handle content as string or content-parts array -#}
294
+ {%- set tool_body = follow.get('content') -%}
295
+ {%- if tool_body is string -%}
296
+ {{- format_tool_response_block(ns_tname.name, tool_body) -}}
297
+ {%- elif tool_body is sequence and tool_body is not string -%}
298
+ {%- set ns_txt = namespace(s='') -%}
299
+ {%- for part in tool_body -%}
300
+ {%- if part.get('type') == 'text' -%}
301
+ {%- set ns_txt.s = ns_txt.s + (part.get('text') | default('')) -%}
302
+ {%- endif -%}
303
+ {%- endfor -%}
304
+ {{- format_tool_response_block(ns_tname.name, ns_txt.s) -}}
305
+ {%- for part in tool_body -%}
306
+ {%- if part.get('type') in ['image', 'image_url'] -%}
307
+ {{- '<|image|>' -}}
308
+ {%- elif part.get('type') in ['audio', 'input_audio'] -%}
309
+ {{- '<|audio|>' -}}
310
+ {%- elif part.get('type') == 'video' -%}
311
+ {{- '<|video|>' -}}
312
+ {%- endif -%}
313
+ {%- endfor -%}
314
+ {%- else -%}
315
+ {{- format_tool_response_block(ns_tname.name, tool_body) -}}
316
+ {%- endif -%}
317
+ {%- set ns_tr_out.flag = true -%}
318
+ {%- set ns.prev_message_type = 'tool_response' -%}
319
+ {%- endif -%}
320
+ {%- endfor -%}
321
+ {%- endif -%}
322
+
323
+ {%- set captured_content -%}
324
+ {%- if message.get('content') is string -%}
325
+ {%- if role == 'model' -%}
326
+ {{- strip_thinking(message['content']) -}}
327
+ {%- else -%}
328
+ {{- message['content'] | trim -}}
329
+ {%- endif -%}
330
+ {%- elif message.get('content') is sequence -%}
331
+ {%- for item in message['content'] -%}
332
+ {%- if item.get('type') == 'text' -%}
333
+ {%- if role == 'model' -%}
334
+ {{- strip_thinking(item['text']) -}}
335
+ {%- else -%}
336
+ {{- item['text'] | trim -}}
337
+ {%- endif -%}
338
+ {%- elif item.get('type') in ['image', 'image_url'] -%}
339
+ {{- '<|image|>' -}}
340
+ {%- elif item.get('type') in ['audio', 'input_audio'] -%}
341
+ {{- '<|audio|>' -}}
342
+ {%- elif item.get('type') == 'video' -%}
343
+ {{- '<|video|>' -}}
344
+ {%- endif -%}
345
+ {%- endfor -%}
346
+ {%- endif -%}
347
+ {%- endset -%}
348
+
349
+ {{- captured_content -}}
350
+ {%- set has_content = captured_content | trim | length > 0 -%}
351
+
352
+ {#- Forward-scan: find next non-tool message role for continuation detection -#}
353
+ {%- set next_nt = namespace(role=None, found=false) -%}
354
+ {%- for j in range(loop.index0 + 1, loop_messages | length) -%}
355
+ {%- if not next_nt.found -%}
356
+ {%- if loop_messages[j]['role'] != 'tool' -%}
357
+ {%- set next_nt.role = loop_messages[j]['role'] -%}
358
+ {%- set next_nt.found = true -%}
359
+ {%- endif -%}
360
+ {%- endif -%}
361
+ {%- endfor -%}
362
+
363
+ {%- set continues_into_next = (
364
+ role == 'model'
365
+ and next_nt.role == 'assistant'
366
+ and (not message.get('tool_calls') or ns_tr_out.flag)
367
+ ) -%}
368
+
369
+ {%- if ns.prev_message_type == 'tool_call' and not ns_tr_out.flag -%}
370
+ {{- '<|tool_response>' -}}
371
+ {%- elif continues_into_next -%}
372
+ {%- elif not (ns_tr_out.flag and not has_content and not next_nt.found) -%}
373
+ {{- '<turn|>\n' -}}
374
+ {%- endif -%}
375
+
376
+ {#- Track previous non-tool role for next iteration (avoids O(n) backward scan) -#}
377
+ {%- set ns.prev_non_tool_role = message['role'] -%}
378
+ {%- endif -%}
379
+ {%- endfor -%}
380
+
381
+ {%- if add_generation_prompt -%}
382
+ {%- if ns.prev_message_type != 'tool_response' and ns.prev_message_type != 'tool_call' -%}
383
+ {{- '<|turn>model\n' -}}
384
+ {%- if not enable_thinking -%}
385
+ {{- '<|channel>thought\n<channel|>' -}}
386
+ {%- endif -%}
387
+ {%- elif ns.prev_message_type == 'tool_response' and enable_thinking -%}
388
+ {{- '<|channel>thought\n' -}}
389
+ {%- endif -%}
390
+ {%- endif -%}
config.json ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Gemma4ForConditionalGeneration"
4
+ ],
5
+ "audio_config": null,
6
+ "audio_token_id": 258881,
7
+ "boa_token_id": 256000,
8
+ "boi_token_id": 255999,
9
+ "dtype": "bfloat16",
10
+ "eoa_token_id": 258883,
11
+ "eoa_token_index": 258883,
12
+ "eoi_token_id": 258882,
13
+ "eos_token_id": [
14
+ 1,
15
+ 106
16
+ ],
17
+ "image_token_id": 258880,
18
+ "initializer_range": 0.02,
19
+ "model_type": "gemma4",
20
+ "text_config": {
21
+ "attention_bias": false,
22
+ "attention_dropout": 0.0,
23
+ "attention_k_eq_v": true,
24
+ "bos_token_id": 2,
25
+ "dtype": "float32",
26
+ "enable_moe_block": false,
27
+ "eos_token_id": 1,
28
+ "expert_intermediate_size": null,
29
+ "final_logit_softcapping": 30.0,
30
+ "global_head_dim": 512,
31
+ "head_dim": 256,
32
+ "hidden_activation": "gelu_pytorch_tanh",
33
+ "hidden_size": 5376,
34
+ "hidden_size_per_layer_input": 0,
35
+ "initializer_range": 0.02,
36
+ "intermediate_size": 21504,
37
+ "layer_types": [
38
+ "sliding_attention",
39
+ "sliding_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "sliding_attention",
43
+ "full_attention",
44
+ "sliding_attention",
45
+ "sliding_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "sliding_attention",
49
+ "full_attention",
50
+ "sliding_attention",
51
+ "sliding_attention",
52
+ "sliding_attention",
53
+ "sliding_attention",
54
+ "sliding_attention",
55
+ "full_attention",
56
+ "sliding_attention",
57
+ "sliding_attention",
58
+ "sliding_attention",
59
+ "sliding_attention",
60
+ "sliding_attention",
61
+ "full_attention",
62
+ "sliding_attention",
63
+ "sliding_attention",
64
+ "sliding_attention",
65
+ "sliding_attention",
66
+ "sliding_attention",
67
+ "full_attention",
68
+ "sliding_attention",
69
+ "sliding_attention",
70
+ "sliding_attention",
71
+ "sliding_attention",
72
+ "sliding_attention",
73
+ "full_attention",
74
+ "sliding_attention",
75
+ "sliding_attention",
76
+ "sliding_attention",
77
+ "sliding_attention",
78
+ "sliding_attention",
79
+ "full_attention",
80
+ "sliding_attention",
81
+ "sliding_attention",
82
+ "sliding_attention",
83
+ "sliding_attention",
84
+ "sliding_attention",
85
+ "full_attention",
86
+ "sliding_attention",
87
+ "sliding_attention",
88
+ "sliding_attention",
89
+ "sliding_attention",
90
+ "sliding_attention",
91
+ "full_attention",
92
+ "sliding_attention",
93
+ "sliding_attention",
94
+ "sliding_attention",
95
+ "sliding_attention",
96
+ "sliding_attention",
97
+ "full_attention"
98
+ ],
99
+ "max_position_embeddings": 262144,
100
+ "model_type": "gemma4_text",
101
+ "moe_intermediate_size": null,
102
+ "num_attention_heads": 32,
103
+ "num_experts": null,
104
+ "num_global_key_value_heads": 4,
105
+ "num_hidden_layers": 60,
106
+ "num_key_value_heads": 16,
107
+ "num_kv_shared_layers": 0,
108
+ "pad_token_id": 0,
109
+ "rms_norm_eps": 1e-06,
110
+ "rope_parameters": {
111
+ "full_attention": {
112
+ "partial_rotary_factor": 0.25,
113
+ "rope_theta": 1000000.0,
114
+ "rope_type": "proportional"
115
+ },
116
+ "sliding_attention": {
117
+ "rope_theta": 10000.0,
118
+ "rope_type": "default"
119
+ }
120
+ },
121
+ "sliding_window": 1024,
122
+ "tie_word_embeddings": true,
123
+ "top_k_experts": null,
124
+ "use_bidirectional_attention": "vision",
125
+ "use_cache": true,
126
+ "use_double_wide_mlp": false,
127
+ "vocab_size": 262144,
128
+ "vocab_size_per_layer_input": 262144
129
+ },
130
+ "tie_word_embeddings": true,
131
+ "transformers_version": "5.12.1",
132
+ "video_token_id": 258884,
133
+ "vision_config": {
134
+ "_name_or_path": "",
135
+ "architectures": null,
136
+ "attention_bias": false,
137
+ "attention_dropout": 0.0,
138
+ "chunk_size_feed_forward": 0,
139
+ "default_output_length": 280,
140
+ "dtype": "float32",
141
+ "global_head_dim": 72,
142
+ "head_dim": 72,
143
+ "hidden_activation": "gelu_pytorch_tanh",
144
+ "hidden_size": 1152,
145
+ "id2label": {
146
+ "0": "LABEL_0",
147
+ "1": "LABEL_1"
148
+ },
149
+ "initializer_range": 0.02,
150
+ "intermediate_size": 4304,
151
+ "is_encoder_decoder": false,
152
+ "label2id": {
153
+ "LABEL_0": 0,
154
+ "LABEL_1": 1
155
+ },
156
+ "max_position_embeddings": 131072,
157
+ "model_type": "gemma4_vision",
158
+ "num_attention_heads": 16,
159
+ "num_hidden_layers": 27,
160
+ "num_key_value_heads": 16,
161
+ "output_attentions": false,
162
+ "output_hidden_states": false,
163
+ "patch_size": 16,
164
+ "pooling_kernel_size": 3,
165
+ "position_embedding_size": 10240,
166
+ "problem_type": null,
167
+ "return_dict": true,
168
+ "rms_norm_eps": 1e-06,
169
+ "rope_parameters": {
170
+ "rope_theta": 100.0,
171
+ "rope_type": "default"
172
+ },
173
+ "standardize": true,
174
+ "use_clipped_linears": false
175
+ },
176
+ "vision_soft_tokens_per_image": 280,
177
+ "quantization_config": {
178
+ "quant_method": "exl3",
179
+ "version": "1.4.2",
180
+ "bits": 5.0,
181
+ "head_bits": 8,
182
+ "calibration": {
183
+ "rows": 250,
184
+ "cols": 2048
185
+ },
186
+ "out_scales": "always",
187
+ "codebook": "mul1"
188
+ }
189
+ }
generation_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 2,
3
+ "do_sample": true,
4
+ "eos_token_id": [
5
+ 1,
6
+ 106,
7
+ 50
8
+ ],
9
+ "pad_token_id": 0,
10
+ "temperature": 1.0,
11
+ "top_k": 64,
12
+ "top_p": 0.95,
13
+ "transformers_version": "5.12.1"
14
+ }
model-00001-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9e8e8ad14033fecdbe517c022c3aaaf0c318376ab21db75bd7ed46c0b511fd6a
3
+ size 8315298288
model-00002-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3e765a7dbef946a45f2b9e8f1391ef0f8ffcaab3d3aa44e7bc39a5379e7d47bd
3
+ size 8527518272
model-00003-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ae26221e2b35b97ac62598b847e8b4e9f103efd7125bd1dcde44c36e95b0bd85
3
+ size 6859545185
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
preprocessor_config.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "size": {
3
+ "shortest_edge": 4096,
4
+ "longest_edge": 16777216
5
+ },
6
+ "patch_size": 16,
7
+ "temporal_patch_size": 2,
8
+ "merge_size": 2,
9
+ "image_mean": [
10
+ 0.48145466,
11
+ 0.4578275,
12
+ 0.40821073
13
+ ],
14
+ "image_std": [
15
+ 0.26862954,
16
+ 0.26130258,
17
+ 0.27577711
18
+ ],
19
+ "image_processor_type": "Qwen2VLImageProcessorFast"
20
+ }
processor_config.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "audio_ms_per_token": 40,
3
+ "audio_seq_length": 750,
4
+ "feature_extractor": {
5
+ "dither": 0.0,
6
+ "feature_extractor_type": "Gemma4AudioFeatureExtractor",
7
+ "feature_size": 128,
8
+ "fft_length": 512,
9
+ "fft_overdrive": false,
10
+ "frame_length": 320,
11
+ "hop_length": 160,
12
+ "input_scale_factor": 1.0,
13
+ "max_frequency": 8000.0,
14
+ "mel_floor": 0.001,
15
+ "min_frequency": 0.0,
16
+ "padding_side": "right",
17
+ "padding_value": 0.0,
18
+ "per_bin_mean": null,
19
+ "per_bin_stddev": null,
20
+ "preemphasis": 0.0,
21
+ "preemphasis_htk_flavor": true,
22
+ "return_attention_mask": true,
23
+ "sampling_rate": 16000
24
+ },
25
+ "image_processor": {
26
+ "do_convert_rgb": true,
27
+ "do_normalize": false,
28
+ "do_rescale": true,
29
+ "do_resize": true,
30
+ "image_mean": [
31
+ 0.0,
32
+ 0.0,
33
+ 0.0
34
+ ],
35
+ "image_processor_type": "Gemma4ImageProcessor",
36
+ "image_seq_length": 280,
37
+ "image_std": [
38
+ 1.0,
39
+ 1.0,
40
+ 1.0
41
+ ],
42
+ "max_soft_tokens": 280,
43
+ "patch_size": 16,
44
+ "pooling_kernel_size": 3,
45
+ "resample": 3,
46
+ "rescale_factor": 0.00392156862745098
47
+ },
48
+ "image_seq_length": 280,
49
+ "processor_class": "Gemma4Processor",
50
+ "video_processor": {
51
+ "do_convert_rgb": true,
52
+ "do_normalize": true,
53
+ "do_rescale": true,
54
+ "do_resize": true,
55
+ "do_sample_frames": true,
56
+ "image_mean": [
57
+ 0.0,
58
+ 0.0,
59
+ 0.0
60
+ ],
61
+ "image_std": [
62
+ 1.0,
63
+ 1.0,
64
+ 1.0
65
+ ],
66
+ "max_soft_tokens": 70,
67
+ "num_frames": 32,
68
+ "patch_size": 16,
69
+ "pooling_kernel_size": 3,
70
+ "resample": 3,
71
+ "rescale_factor": 0.00392156862745098,
72
+ "return_metadata": false,
73
+ "video_processor_type": "Gemma4VideoProcessor"
74
+ }
75
+ }
quantization_config.json ADDED
The diff for this file is too large to render. See raw diff
 
scotoma-2-hero.webp ADDED
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f
3
+ size 32169626
tokenizer_config.json ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "audio_token": "<|audio|>",
3
+ "backend": "tokenizers",
4
+ "boa_token": "<|audio>",
5
+ "boi_token": "<|image>",
6
+ "bos_token": "<bos>",
7
+ "eoa_token": "<audio|>",
8
+ "eoc_token": "<channel|>",
9
+ "eoi_token": "<image|>",
10
+ "eos_token": "<eos>",
11
+ "eot_token": "<turn|>",
12
+ "escape_token": "<|\"|>",
13
+ "etc_token": "<tool_call|>",
14
+ "etd_token": "<tool|>",
15
+ "etr_token": "<tool_response|>",
16
+ "extra_special_tokens": [
17
+ "<|video|>"
18
+ ],
19
+ "image_token": "<|image|>",
20
+ "is_local": true,
21
+ "local_files_only": false,
22
+ "mask_token": "<mask>",
23
+ "model_max_length": 1000000000000000019884624838656,
24
+ "model_specific_special_tokens": {
25
+ "audio_token": "<|audio|>",
26
+ "boa_token": "<|audio>",
27
+ "boi_token": "<|image>",
28
+ "eoa_token": "<audio|>",
29
+ "eoc_token": "<channel|>",
30
+ "eoi_token": "<image|>",
31
+ "eot_token": "<turn|>",
32
+ "escape_token": "<|\"|>",
33
+ "etc_token": "<tool_call|>",
34
+ "etd_token": "<tool|>",
35
+ "etr_token": "<tool_response|>",
36
+ "image_token": "<|image|>",
37
+ "soc_token": "<|channel>",
38
+ "sot_token": "<|turn>",
39
+ "stc_token": "<|tool_call>",
40
+ "std_token": "<|tool>",
41
+ "str_token": "<|tool_response>",
42
+ "think_token": "<|think|>"
43
+ },
44
+ "pad_token": "<pad>",
45
+ "padding_side": "left",
46
+ "processor_class": "Gemma4Processor",
47
+ "response_schema": {
48
+ "properties": {
49
+ "content": {
50
+ "type": "string"
51
+ },
52
+ "role": {
53
+ "const": "assistant"
54
+ },
55
+ "thinking": {
56
+ "type": "string"
57
+ },
58
+ "tool_calls": {
59
+ "items": {
60
+ "properties": {
61
+ "function": {
62
+ "properties": {
63
+ "arguments": {
64
+ "additionalProperties": {},
65
+ "type": "object",
66
+ "x-parser": "gemma4-tool-call"
67
+ },
68
+ "name": {
69
+ "type": "string"
70
+ }
71
+ },
72
+ "type": "object",
73
+ "x-regex": "call\\:(?P<name>\\w+)(?P<arguments>\\{.*\\})"
74
+ },
75
+ "type": {
76
+ "const": "function"
77
+ }
78
+ },
79
+ "type": "object"
80
+ },
81
+ "type": "array",
82
+ "x-regex-iterator": "<\\|tool_call>(.*?)<tool_call\\|>"
83
+ }
84
+ },
85
+ "type": "object",
86
+ "x-regex": "(\\<\\|channel\\>thought\\n(?P<thinking>.*?)\\<channel\\|\\>)?(?P<tool_calls>\\<\\|tool_call\\>.*\\<tool_call\\|\\>)?(?P<content>(?:(?!\\<turn\\|\\>)(?!\\<\\|tool_response\\>).)+)?(?:\\<turn\\|\\>|\\<\\|tool_response\\>)?"
87
+ },
88
+ "response_template": {
89
+ "defaults": {
90
+ "role": "assistant"
91
+ },
92
+ "fields": {
93
+ "content": {
94
+ "close": [
95
+ "<turn|>",
96
+ "<|tool_response>",
97
+ "<eos>"
98
+ ],
99
+ "content": "text"
100
+ },
101
+ "thinking": {
102
+ "close": "<channel|>",
103
+ "content": "text",
104
+ "open": "<|channel>thought\n"
105
+ },
106
+ "tool_calls": {
107
+ "close": "<tool_call|>",
108
+ "content": "json",
109
+ "content_args": {
110
+ "string_delims": [
111
+ [
112
+ "<|\"|>",
113
+ "<|\"|>"
114
+ ]
115
+ ],
116
+ "unquoted_keys": true
117
+ },
118
+ "open_pattern": "<\\|tool_call>call:(?P<name>\\w+)",
119
+ "repeats": true,
120
+ "transform": {
121
+ "function": {
122
+ "arguments": "{content}",
123
+ "name": "{name}"
124
+ },
125
+ "type": "function"
126
+ }
127
+ }
128
+ },
129
+ "start_anchor": [
130
+ "<|turn>model\n",
131
+ "<tool_response|>"
132
+ ]
133
+ },
134
+ "soc_token": "<|channel>",
135
+ "sot_token": "<|turn>",
136
+ "stc_token": "<|tool_call>",
137
+ "std_token": "<|tool>",
138
+ "str_token": "<|tool_response>",
139
+ "think_token": "<|think|>",
140
+ "tokenizer_class": "GemmaTokenizer",
141
+ "unk_token": "<unk>"
142
+ }