<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kontekst — Inferownia</title><link>https://inferownia.pl/tags/kontekst/</link><description>Inferownia — polski hub wiedzy o lokalnym AI: uruchamianie modeli językowych na własnym sprzęcie, kwantyzacja, inferencja, małe modele, fine-tuning i RAG.</description><language>pl-PL</language><copyright>&#169; 2026 Inferownia</copyright><lastBuildDate>Sun, 05 Jul 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://inferownia.pl/tags/kontekst/index.xml" rel="self" type="application/rss+xml"/><item><title>YaRN: jak rozciągnąć kontekst, którego model nie widział</title><link>https://inferownia.pl/naukowy/yarn-kontekst/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0200</pubDate><author>Bowen Peng</author><author>Jeffrey Quesnelle</author><author>Honglu Fan</author><author>Enrico Shippole</author><category>inferencja</category><guid>https://inferownia.pl/naukowy/yarn-kontekst/</guid><description>Model uczony na 4 tysiącach tokenów nagle ogarnia 128 tysięcy. Nie magia, nie retrening od zera — tylko sprytne przekręcenie zegara pozycji w RoPE i kilkaset kroków douczenia.</description><content:encoded><![CDATA[<p>Przewijasz kartę modelu na Hugging Face i w tabelce mruga do ciebie „128k context”.
Sto dwadzieścia osiem tysięcy tokenów — cała książka wleci w jeden prompt. Serce rośnie.
A potem, gdzieś na dole, drobnym druczkiem: model bazowy trenowany na sekwencjach 4096.
No i człowiek głupieje. Jak to? Uczyłeś go patrzeć na cztery tysiące tokenów naraz, a teraz
ma ogarnąć trzydzieści dwa razy więcej? Skąd on niby wie, jak wygląda token numer 100 000,
skoro w życiu takiego nie widział?</p>
<p>To nie jest pytanie z gatunku czepialstwa. Sam pewnie nieraz widziałeś, jak model
z „długim kontekstem” pięknie streszcza pierwsze pięć stron, a od dziesiątej zaczyna
zmyślać, mieszać imiona i gubić wątek — dokładnie w miejscu, w którym teoretycznie
miał błyszczeć. Bo rozciąganie okna kontekstu to nie jest przesunięcie
suwaka. To operacja na sercu tego, jak model w ogóle rozumie „gdzie” jest dany token.
I tu wchodzi YaRN — metoda z pracy grupy z Nous Research, która robi to tanio i, co
ważniejsze, robi to dobrze.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<h2 id="skąd-model-w-ogóle-wie-który-token-jest-który">Skąd model w ogóle wie, który token jest który</h2>
<p>Zacznijmy od tego, że transformer sam z siebie nie ma pojęcia o kolejności. Wrzuć mu
„pies goni kota” i „kota goni pies” — bez informacji o pozycji to dla niego ta sama torba
słów. Trzeba mu jakoś powiedzieć, że ten token jest pierwszy, tamten setny.</p>
<p>Współczesne modele — LLaMA, Mistral, Qwen — robią to przez <strong>RoPE</strong> (<em>rotary position
embeddings</em>, rotacyjne osadzenia pozycyjne) z pracy Su i innych.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> Pomysł jest
elegancki: zamiast doklejać pozycję jako osobny wektor, RoPE <strong>obraca</strong> wektory zapytań
i kluczy o kąt proporcjonalny do pozycji tokena. Każdy wymiar embeddingu kręci się z inną
częstotliwością — jedne szybko, jak wskazówka sekundowa, inne wolno, jak godzinowa. Token
na pozycji 5 jest obrócony trochę, token na pozycji 5000 — dużo. Model uczy się czytać
te kąty i z różnicy obrotów między dwoma tokenami wnioskuje, jak daleko od siebie leżą.</p>
<p>I teraz clou problemu: model widział te wskazówki tykające tylko do pozycji 4096. Dalej
jest terra incognita. Kąty, które w treningu nigdy się nie pojawiły. Puść go na token
50 000, a wskazówka sekundowa zakręci się tyle razy, że model nie ma bladego pojęcia, co
z tym zrobić — to jak pokazać komuś zegar, który obrócił się poza tarczę, w miejsce,
którego nigdy nie oznaczono.</p>
<h2 id="dlaczego-po-prostu-ściśnij-pozycje-psuje-robotę">Dlaczego „po prostu ściśnij pozycje” psuje robotę</h2>
<p>Pierwszy odruch jest oczywisty. Skoro model zna zakres do 4096, a chcemy 64k, to
przeskalujmy pozycje liniowo — token 64 000 udawaj, że jesteś tokenem 4000. Ściśnij całą
oś czasu tak, żeby zmieściła się w znanym zakresie. To jest <strong>Position Interpolation</strong> (PI,
interpolacja pozycji) z pracy Chena i innych — i na papierze brzmi rozsądnie.</p>
<p>Problem w tym, że PI traktuje <strong>wszystkie</strong> częstotliwości RoPE jednakowo — zwalnia i
sekundnik, i wskazówkę godzinową o ten sam czynnik.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> A to katastrofa dla tych
najszybszych wymiarów. To właśnie one odpowiadają za rozróżnianie tokenów leżących tuż
obok siebie — „czy słowo A jest bezpośrednio przed B, czy jest między nimi jeszcze jedno”.
Ściśnij je razem z resztą, a model traci rozdzielczość na najdrobniejszym poziomie.
Efekt? Jakość spada nawet na <strong>krótkim</strong> kontekście, który przecież działał bez zarzutu.
Rozciągnąłeś okno i po drodze rozmyłeś to, co model umiał od początku. Klasyczny handel,
w którym oddajesz więcej, niż dostajesz.</p>
<h2 id="jak-yarn-dzieli-częstotliwości-na-pasma">Jak YaRN dzieli częstotliwości na pasma</h2>
<p>No to jak zrobić to mądrzej? Skoro problem jest w tym, że traktujemy wszystkie
częstotliwości jednakowo — to <strong>przestańmy</strong>. To jest cała intuicja YaRN.</p>
<p>Zanim doszli do wersji finalnej, po drodze była <strong>NTK-aware interpolation</strong> (interpolacja
świadoma NTK) — zamiast liniowo ściskać pozycje, zmienia się podstawę RoPE z <code>b</code> na
<code>b * s^(|D|/(|D|-2))</code>, przez co „nacisk” interpolacji rozkłada się nierówno po
wymiarach.<sup id="fnref1:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Lepiej, ale wciąż z grubsza jednym pociągnięciem po wszystkim.</p>
<p>YaRN idzie krok dalej z podejściem <strong>NTK-by-parts</strong> (interpolacja pasmowa) — i to jest
serce metody. Dzielisz wymiary częstotliwości na pasma za pomocą funkcji rampy <code>γ(r)</code>:<sup id="fnref2:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<ul>
<li><strong>wysokie częstotliwości</strong> (te lokalne, szybkie wskazówki — sąsiad przy sąsiedzie)
zostawiasz w spokoju, bez interpolacji. Ekstrapolujesz. Niech tykają jak tykały.</li>
<li><strong>niskie częstotliwości</strong> (te globalne, wolne — gruby zarys „to jest gdzieś na końcu
dokumentu”) interpolujesz normalnie, bo to one muszą pomieścić nowy, większy zakres.</li>
<li>pasmo <strong>pośrodku</strong> rampa miesza płynnie, żeby nie było skoku na styku.</li>
</ul>
<p>Sedno: nie ruszasz tego, co model umie najlepiej (drobna rozdzielczość lokalna), a
rozciągasz tylko to, co i tak opisuje wielką skalę. Zegar dostaje większą tarczę, ale
sekundnik dalej odmierza sekundy tak samo dokładnie.</p>
<table>
	<thead>
			<tr>
					<th>Metoda</th>
					<th>Co robi z częstotliwościami</th>
					<th>Efekt uboczny</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Position Interpolation (PI)</td>
					<td>ściska wszystkie jednakowo, liniowo</td>
					<td>psuje rozdzielczość lokalną, spada jakość i na krótkim kontekście</td>
			</tr>
			<tr>
					<td>NTK-aware</td>
					<td>zmienia podstawę RoPE, nacisk rozkłada nierówno</td>
					<td>lepiej, ale wciąż jeden globalny gest</td>
			</tr>
			<tr>
					<td>NTK-by-parts (YaRN)</td>
					<td>dzieli na pasma rampą <code>γ(r)</code>: wysokie ekstrapoluje, niskie interpoluje</td>
					<td>zachowuje lokalną precyzję, rozciąga tylko skalę globalną</td>
			</tr>
	</tbody>
</table>
<h2 id="drugi-bezpiecznik-temperatura-uwagi">Drugi bezpiecznik: temperatura uwagi</h2>
<p>I tu jest smaczek, który łatwo przegapić, bo nie ma nic wspólnego ze skalowaniem
częstotliwości. YaRN dorzuca <strong>attention temperature scaling</strong> — skalowanie temperatury
w softmaxie uwagi.<sup id="fnref3:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Kiedy rozciągasz kontekst, rozkład uwagi robi się „płaski”,
model rozprasza się na tysiące tokenów zamiast celować. Więc mnożysz logity uwagi przez
stały współczynnik, wyliczony z prostego, empirycznego wzoru:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">sqrt(1/t) = 0.1 * ln(s) + 1
</span></span></code></pre></div><p>gdzie <code>s</code> to współczynnik skalowania kontekstu (dla 4096 → 64k mamy <code>s = 16</code>). Piękne w
tym jest to, że działa jak zwykły mnożnik na logitach — <strong>nie dotyka wag modelu</strong>, nie
wymaga dodatkowego treningu, wchodzi za darmo. Osobne pokrętło, doklejone z boku,
a robi sporo dobrego dla ostrości. Nie pomyl go ze skalowaniem samego RoPE — to dwa różne
mechanizmy, które YaRN łączy w jedno.</p>
<h2 id="tanio-czyli-ile-to-naprawdę-kosztuje">Tanio, czyli ile to naprawdę kosztuje</h2>
<p>Teraz najlepsze — bo tu YaRN naprawdę błyszczy. To <strong>nie</strong> jest trening od zera. To nawet
nie jest porządny fine-tuning na górze danych. To <strong>krótkie douczenie</strong> już gotowego modelu,
żeby oswoił się z nowymi kątami.</p>
<p>Ile krótkie? W pracy LLaMA-2 7B i 13B douczono jakieś <strong>400 kroków</strong> przy <code>s = 16</code>
(4096 → 64k), plus dodatkowe <strong>~200 kroków</strong> przy <code>s = 32</code>, żeby dobić do 128k — razem
około 600 kroków, na danych PG19 w segmentach po 64k, przy batchu 64.<sup id="fnref4:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>
Objętościowo to szacunkowo <strong>~0,1% oryginalnego korpusu</strong> pretreningowego. Jedna dziesiąta
procenta. W liczbach z abstraktu: YaRN potrzebuje około <strong>10x mniej tokenów</strong> douczenia i
<strong>2,5x mniej kroków</strong> treningowych niż wcześniejsze metody.<sup id="fnref1:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>I jeszcze jedna rzecz, która robi wrażenie: modele <strong>ekstrapolują poza</strong> długość, na której
je douczono. Serię Mistral 7B rozciągnięto z 8k do 64k i 128k tą samą metodą — a trening
na segmentach 64k dawał poprawne działanie aż do 128k.<sup id="fnref5:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Model, który w douczeniu
nie widział nic dłuższego niż 64k, radzi sobie dwa razy dalej. To już nie jest tylko
„nauczyliśmy go nowego zakresu” — to „nauczyliśmy go <em>reguły</em>, którą sam rozciąga dalej”.</p>
<div class="callout">
  <span class="callout__label">Dlaczego to ważne dla lokalnego LLM</span>
<p>Dla ciebie, co odpalasz modele lokalnie, to zmienia rachunek na dysku i w głowie. Nie
musisz mieć farmy GPU, żeby dostać model z długim kontekstem — ktoś dorzucił kilkaset
kroków douczenia i wrzucił gotowca na Hugging Face. Ale okno kontekstu to nie darmowy
lunch: każdy dodatkowy tysiąc tokenów to więcej pamięci na KV-cache, a to on, nie wagi,
zjada VRAM przy długich promptach — rozgryzaliśmy to bliżej <a href="/poradniki/kv-cache-vram/">tutaj</a>.
128k w tabelce i 128k, które faktycznie wejdzie na twoją kartę, to dwie różne historie.</p>
</div>
<h2 id="zrób-to-sam-yarn-w-llamacpp">Zrób to sam: YaRN w llama.cpp</h2>
<p>I teraz uwaga na rozróżnienie, na którym łatwo się wyłożyć. Wszystko powyżej — kroki
douczenia, dane PG19 — to warstwa <strong>treningu</strong> opisana w papierze. Ale jest druga warstwa:
<strong>inferencja</strong>. <code>llama.cpp</code> implementuje skalowanie YaRN jako parametry runtime, które
przekręcasz przy uruchomieniu, bez żadnego douczania:<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">llama-server -m model-yarn-128k.gguf <span class="se">\
</span></span></span><span class="line"><span class="cl">  -c <span class="m">65536</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --yarn-orig-ctx <span class="m">8192</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --yarn-ext-factor 1.0 <span class="se">\
</span></span></span><span class="line"><span class="cl">  -fa on
</span></span></code></pre></div><ul>
<li><strong><code>--yarn-orig-ctx</code></strong> — oryginalny kontekst treningowy modelu (domyślnie <code>0</code>, czyli
„wczytaj z metadanych GGUF”). To punkt odniesienia, względem którego liczy się <code>s</code>.</li>
<li><strong><code>--yarn-ext-factor</code></strong> — współczynnik mieszania ekstrapolacji (domyślnie <code>-1.00</code>;
<code>0.0</code> to pełna interpolacja).</li>
</ul>
<p>Jeśli model został wypuszczony jako wariant YaRN, metadane zwykle same podpowiedzą sensowne
wartości — wtedy w ogóle nie musisz w to grzebać. A jak flagi w <code>llama.cpp</code> w ogóle działają
i które z tej setki naprawdę musisz znać, rozbieraliśmy <a href="/poradniki/flagi-llama-cpp/">w osobnym wpisie</a>.
Jest jeszcze wariant <strong>Dynamic NTK</strong> — aktualizuje współczynnik skalowania <code>s = max(1, l'/L)</code>
w locie, per krok inferencji, zamiast trzymać stałą wartość ustaloną raz.<sup id="fnref6:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Sprytne,
bo krótkie prompty nie płacą podatku za rozciągnięcie, którego akurat nie potrzebują.</p>
<p>Cała ta rodzina metod, swoją drogą, ładnie zazębia się z tym, jak w ogóle liczy się uwaga —
a to temat, który drążyliśmy przy <a href="/naukowy/flashattention/">FlashAttention</a>.</p>
<h2 id="większa-tarcza-ten-sam-sekundnik">Większa tarcza, ten sam sekundnik</h2>
<p>Wróćmy na koniec do tego zegara. Naiwna interpolacja bierze tarczę i ściska ją tak, że
sekundnik zlewa się z minutową — niby zmieściłeś więcej godzin, ale nie odczytasz już,
czy jest 12:01, czy 12:02. YaRN robi odwrotnie: zostawia sekundnik w spokoju, a rozciąga
tylko wolne wskazówki, które i tak odmierzają grube kawałki. Dokładasz kilkaset kroków
douczenia — tyle, ile trzeba, żeby model oswoił nowe kąty — i nagle patrzy na sto
dwadzieścia osiem tysięcy tokenów tak, jakby zawsze umiał. Nie dlatego, że zobaczył każdą
nową pozycję. Dlatego, że ktoś mądrze przekręcił mu zegar, nie tłukąc szkła.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Bowen Peng, Jeffrey Quesnelle, Honglu Fan, Enrico Shippole, „YaRN: Efficient Context Window Extension of Large Language Models”, <a href="https://arxiv.org/abs/2309.00071">arXiv:2309.00071</a> (v1 z 31 sierpnia 2023, v2 z 1 listopada 2023). Abstrakt: ok. 10x mniej tokenów i 2,5x mniej kroków treningowych niż wcześniejsze metody.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Jianlin Su i in., „RoFormer: Enhanced Transformer with Rotary Position Embedding”, <a href="https://arxiv.org/abs/2104.09864">arXiv:2104.09864</a> — oryginalna praca o RoPE, na której stoi cała ta rodzina metod.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>Szczegóły techniczne (krytyka Position Interpolation, definicje NTK-aware / NTK-by-parts / Dynamic NTK, wzór na skalowanie temperatury uwagi, liczby kroków douczenia i długości kontekstu, eksperymenty na Mistral 7B) — pełny tekst pracy w wersji HTML: <a href="https://ar5iv.labs.arxiv.org/html/2309.00071">ar5iv.labs.arxiv.org/html/2309.00071</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref3:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref4:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref5:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref6:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>Parametry runtime <code>--yarn-orig-ctx</code> i <code>--yarn-ext-factor</code> w <code>llama.cpp</code> — dokumentacja serwera: <a href="https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md">ggml-org/llama.cpp, tools/server/README.md</a>.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>Nowy model? Na co patrzeć, zanim go ściągniesz</title><link>https://inferownia.pl/aktualnosci/nowy-model-na-co-patrzec/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0200</pubDate><category>małe-modele</category><guid>https://inferownia.pl/aktualnosci/nowy-model-na-co-patrzec/</guid><description>Świeży model wpada na Hugging Face, scena huczy, a ty już masz palec nad przyciskiem pobierania. Zanim klikniesz, przejdź tę krótką listę — oszczędzi ci wieczoru walki z czymś, co i tak nie chciało ruszyć.</description><content:encoded><![CDATA[<p>„NEW SOTA MODEL DROPPED&quot;. Wątek puchnie w oczach,
w komentarzach lawina wykrzykników, ktoś już pokazuje screena, jak model rozwiązuje
zagadkę o wilku, kozie i kapuście, a ty siedzisz i czujesz, że folder <code>models</code> zaraz
znowu spuchnie o kolejne kilka giga. Palec sam wędruje nad „Download&quot;. I to jest właśnie
ten moment, w którym warto na sekundę zdjąć rękę z myszki.</p>
<p>Bo entuzjazm sceny jest szczery, ale scena nie odpala tego modelu na twojej karcie. Ty
odpalasz. I między „premiera na Hugging Face&quot; a „gada u ciebie w terminalu tak, jak powinno&quot;
leży kilka pułapek, które regularnie kosztują ludzi wieczór. Dobra wiadomość: da się je
odhaczyć w pięć minut, jeszcze zanim cokolwiek pobierzesz. Zrobimy z tego listę — taką,
którą przejdziesz przy każdym kolejnym „SOTA&quot;, bo modeli będzie jeszcze wysyp.</p>
<h2 id="karta-modelu-czyli-tabliczka-znamionowa">Karta modelu, czyli tabliczka znamionowa</h2>
<p>Zanim cokolwiek zrobisz — otwórz kartę modelu. Na Hugging Face to nie żaden osobny dokument,
tylko plik <code>README.md</code> w repo, a na jego górze siedzi kawałek metadanych w YAML-u.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
To jest tabliczka znamionowa: licencja, model bazowy, czasem gotowe wyniki ewaluacji.
Cała ta lista, którą zaraz przejdziemy, w dużej mierze czyta się właśnie stamtąd. Nauczysz
się rzucać okiem na te kilka pól i połowa niespodzianek znika, zanim się wydarzy.</p>
<h2 id="ile-ten-model-waży-i-w-jakim-wariancie">Ile ten model waży i w jakim wariancie?</h2>
<p>Pierwsze pytanie brutalnie praktyczne: czy to w ogóle wejdzie? Liczba parametrów (te 7B,
8B, 70B w nazwie) to grube przybliżenie apetytu na pamięć, ale w pełnej precyzji nawet
„mały&quot; 8B to kilkanaście giga. Dlatego naprawdę interesuje cię, czy istnieje wersja
skwantyzowana — a konkretnie, czy ktoś zrobił już pliki <strong>GGUF</strong>, format, którego używają
<code>llama.cpp</code> i Ollama.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<p>Kwantyzacja to nic innego jak zapisanie tych miliardów wag ciaśniej: mniej bitów na liczbę,
mniejszy plik, mniejszy apetyt na VRAM, a jakość spada zaskakująco mało. Dokumentacja
<code>llama.cpp</code> podaje wprost skalę: Llama-3.1-8B w formacie F16 waży jakieś 14,96 GiB, a ta
sama w Q4_K_M — około 4,58 GiB.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Trzy razy mniej, a <code>Q4_K_M</code> to poziom, który regularnie
pada jako rozsądny kompromis rozmiar-jakość. Co znaczą wszystkie te literki i cyferki po
<code>Q</code>, rozgryzaliśmy osobno <a href="/poradniki/nazwy-kwantyzacji-gguf/">tutaj</a>.</p>
<p>Jedno małe ostrzeżenie, żeby nie pomylić pojęć: kwantyzacja po treningu (to, co dostajesz
w GGUF-ie) to nie to samo, co trenowanie modelu od zera w niskiej precyzji. Dwie różne
rzeczy, różny wpływ na jakość. Ktoś na scenie zawsze je pomiesza — nie bądź tym kimś.</p>
<h2 id="czy-w-ogóle-wolno-ci-go-użyć">Czy w ogóle wolno ci go użyć?</h2>
<p>To pole, które ludzie przewijają najszybciej, a które potrafi najbardziej zaboleć.
W metadanych karty jest <code>license:</code> — identyfikator licencji, po którym Hub nawet pozwala
filtrować modele.<sup id="fnref1:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> I tu jest haczyk: samo to, że repo jest otwarte i pliki leżą do
pobrania, nie znaczy, że wolno ci na tym modelu zbudować cokolwiek komercyjnego.</p>
<p>Część modeli jedzie na licencjach „społecznościowych&quot; albo „research only&quot;, które
uśmiechają się otwarcie, a w treści ograniczają użycie. Gdy w polu widzisz <code>license: other</code>,
to sygnał, żeby kliknąć w <code>license_link</code> i faktycznie przeczytać, na co się piszesz — bo
identyfikator sam z siebie nic ci nie gwarantuje.<sup id="fnref2:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> Nudne? Nudne. Ale to jedyny punkt
z tej listy, który może się skończyć rozmową z prawnikiem, a nie z terminalem.</p>
<h2 id="jak-długi-kontekst-realnie-dostaniesz">Jak długi kontekst realnie dostaniesz?</h2>
<p>Model w karcie chwali się 128k kontekstu, więc bierzesz go do przełykania całych PDF-ów —
i tu wpadasz w klasyczne nieporozumienie. Deklarowane maksimum modelu to jedno, a okno,
które faktycznie ustawi ci runtime, to drugie.</p>
<p>Ollama na przykład sama dobiera domyślną długość kontekstu do tego, ile masz VRAM-u: przy
mniej niż 24 GiB da ci 4k, a dopiero przy 48 GiB i więcej sięga nawet po 256k.<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>
Czyli twój wypasiony 128k model może po cichu chodzić na czterech tysiącach tokenów, a ty
się dziwisz, czemu „zapomina&quot; początek dokumentu. Wymusisz to zmienną <code>OLLAMA_CONTEXT_LENGTH</code>
albo parametrem <code>num_ctx</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">OLLAMA_CONTEXT_LENGTH</span><span class="o">=</span><span class="m">64000</span> ollama serve
</span></span></code></pre></div><p>A ustawić to okno możesz na kilka sposobów i jest wśród nich hierarchia: <code>PARAMETER num_ctx</code>
w Modelfile ustala okno na stałe dla danego modelu, a opcje podane w locie w wywołaniu API
nadpisują to, co siedzi w Modelfile.<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> Tylko pamiętaj o dwóch kosztach: większe okno
to znacznie więcej pamięci — dokumentacja Ollamy mówi to wprost — a siłą rzeczy także wolniejsze
liczenie.<sup id="fnref1:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> Do tego rozciąganie okna ponad długość, na jakiej model trenowano, potrafi
pogorszyć jakość odpowiedzi; dokładnie ten problem rozbraja mechanizm YaRN, który rozłożyliśmy
na części <a href="/naukowy/yarn-kontekst/">tu</a>. W <code>llama.cpp</code> tym samym oknem steruje flaga <code>-c</code>.</p>
<h2 id="czy-narzędzie-w-ogóle-to-obsłuży">Czy narzędzie w ogóle to obsłuży?</h2>
<p>Najboleśniejsza pułapka premierowa: model jest na Hugging Face, więc zakładasz, że od razu
odpalisz go w <code>llama.cpp</code> czy Ollamie. A to wcale nie jest automatyczne. <code>llama.cpp</code> wymaga
formatu GGUF, a jak model przychodzi w innym formacie, ktoś musi go najpierw skonwertować
skryptami <code>convert_*.py</code> z repo (Hugging Face udostępnia do tego nawet przestrzeń
„GGUF-my-repo&quot;).<sup id="fnref1:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<p>Gorzej, gdy model przynosi <strong>nową architekturę</strong>. Wtedy wsparcia po prostu nie ma, dopóki
ktoś go nie dopisze — a to nie jest jedna linijka. Trzeba ruszyć skrypty konwersji w Pythonie
(mapowanie tensorów, <code>constants.py</code>, <code>tensor_mapping.py</code>), potem kod C++ (<code>llama-arch</code>,
<code>llama-model-loader</code>, <code>llama-model</code>, obsługa RoPE), a na koniec przetestować to na CPU, CUDA
i Metalu.<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup> Dlatego dzień premiery modelu i dzień pierwszego działającego GGUF-a to
często dwie różne daty. Jak śledzisz świeżynkę, sprawdź najpierw, czy w issues repo ktoś już
nie ogarnia integracji — o tym, jak w ogóle działa ten cały ekosystem wokół GGUF-a, pisaliśmy
<a href="/aktualnosci/ekosystem-gguf/">osobno</a>.</p>
<h2 id="instruct-czy-base-sprawdź-zanim-się-zdziwisz">Instruct czy base? Sprawdź, zanim się zdziwisz</h2>
<p>Widzisz w nazwie samo „Llama-3-8B&quot; bez dopisku i myślisz, że pogadasz. Odpalasz, piszesz
pytanie, a model zamiast odpowiedzieć — dopisuje kolejne pytania. Nie zepsuł się. Wziąłeś
wersję <strong>base</strong>, która tylko kontynuuje sekwencję tokenów, zamiast wersji <strong>instruct/chat</strong>,
douczonej do podążania za poleceniami i dialogiem.<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup></p>
<p>Różnica jest fundamentalna, a diabeł siedzi w formacie. Model czatowy oczekuje wiadomości
opakowanych w konkretne tokeny kontrolne — u jednego to <code>[INST]...[/INST]</code>, u innego
<code>&lt;|user|&gt;</code> i <code>&lt;|assistant|&gt;</code> — i co gorsza, dwa modele dotrenowane z tej samej bazy mogą mieć
zupełnie różny format czatu.<sup id="fnref1:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup> Podasz zły — i instruct-model, który powinien świecić,
nagle gada od rzeczy. W bibliotece <code>transformers</code> załatwia to <code>apply_chat_template</code>, który
sam skleja wiadomości w format właściwy dla danego modelu.<sup id="fnref2:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup> W <code>llama.cpp</code> odpowiada za
to <code>--jinja</code>. Morał krótki: zajrzyj do karty i upewnij się, który to wariant, zanim ogłosisz,
że „model jest słaby&quot;.</p>
<h2 id="benchmarki-tak-ale-z-ręką-na-sercu">Benchmarki? Tak, ale z ręką na sercu</h2>
<p>I na koniec ta tabelka, przez którą w ogóle klikasz „Download&quot; — słupki, w których nowy
model bije wszystko dookoła. Model card może nawet nieść ustrukturyzowane wyniki w polu
<code>model-index</code>, z zadaniem, datasetem, metryką i źródłem.<sup id="fnref3:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> Fajnie. Tylko traktuj to jak
deklarację producenta, nie jak wyrok.</p>
<p>Jest udokumentowany problem zwany <strong>benchmark data contamination</strong>: dane testowe benchmarku
wyciekają do zbioru treningowego modelu, przez co wynik na tym teście rośnie bez realnej
poprawy jakości.<sup id="fnref:8"><a href="#fn:8" class="footnote-ref" role="doc-noteref">8</a></sup> Model po prostu „widział odpowiedzi&quot; na egzaminie. To nie teoria
spiskowa — poświęcono temu prace przeglądowe. Dlatego liczba w tabelce mówi ci co najwyżej,
że warto sprawdzić samemu na swoim zastosowaniu, a nie że sprawa zamknięta. Najlepszy
benchmark i tak jest jeden: twój własny prompt, którego nikt nie mógł wcześniej wkuć.</p>
<h2 id="zrób-to-sam-lista-na-lodówkę">Zrób to sam: lista na lodówkę</h2>
<p>Cała ta gadka sprowadza się do sześciu spojrzeń w kartę modelu, zanim ruszysz pobieranie:</p>
<table>
	<thead>
			<tr>
					<th>Sprawdź</th>
					<th>Gdzie</th>
					<th>Czerwona flaga</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Rozmiar i wariant</td>
					<td>liczba parametrów, czy jest GGUF (np. <code>Q4_K_M</code>)</td>
					<td>tylko pełna precyzja, brak GGUF</td>
			</tr>
			<tr>
					<td>Licencja</td>
					<td>pole <code>license</code> / <code>license_link</code></td>
					<td><code>other</code> bez przeczytanej treści, „research only&quot;</td>
			</tr>
			<tr>
					<td>Kontekst</td>
					<td>deklaracja modelu vs domyślne okno runtime&rsquo;u</td>
					<td>liczysz na 128k, dostajesz 4k</td>
			</tr>
			<tr>
					<td>Wsparcie narzędzia</td>
					<td>GGUF gotowy? architektura znana <code>llama.cpp</code>?</td>
					<td>świeża architektura, brak konwertera</td>
			</tr>
			<tr>
					<td>Instruct vs base</td>
					<td>dopisek w nazwie, karta modelu</td>
					<td>base tam, gdzie chcesz rozmawiać</td>
			</tr>
			<tr>
					<td>Benchmarki</td>
					<td>tabelka wyników, metodologia</td>
					<td>same słupki bez metody, ryzyko skażenia</td>
			</tr>
	</tbody>
</table>
<p>Wydrukuj, przyklej nad biurkiem, albo po prostu zapamiętaj rytm: waga, licencja, kontekst,
wsparcie, wariant, benchmarki. Przy trzecim nowym modelu przejdziesz to odruchowo.</p>
<p>Bo świeży model to trochę jak używane auto z ogłoszenia: zdjęcia lśnią, opis zachwala, scena
piszczy z zachwytu. Ale to ty siadasz za kierownicą i to ty potem stoisz na poboczu, jak się
okaże, że pod maską nie ma silnika pasującego do twojej karty. Pięć minut zaglądania pod
maskę — kartę modelu — kosztuje mniej niż wieczór klikania w „czemu to nie działa&quot;.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Hugging Face Hub docs — Model Cards (metadane: <code>license</code>, <code>license_name</code>/<code>license_link</code>, <code>base_model</code>/<code>base_model_relation</code>, <code>model-index</code>), <a href="https://huggingface.co/docs/hub/en/model-cards">huggingface.co/docs/hub/en/model-cards</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref3:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>llama.cpp — wymóg formatu GGUF, konwersja skryptami <code>convert_*.py</code>, przestrzeń „GGUF-my-repo&quot;, <a href="https://github.com/ggml-org/llama.cpp/blob/master/README.md">README repo ggml-org/llama.cpp</a>.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>llama.cpp — poziomy kwantyzacji GGUF (IQ*, Q2_K–Q8_0, F16) oraz przykład Llama-3.1-8B: F16 ≈ 14,96 GiB, Q4_K_M ≈ 4,58 GiB, <a href="https://github.com/ggml-org/llama.cpp/blob/master/tools/quantize/README.md">tools/quantize/README.md</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>Ollama docs — Context length: domyślne dobieranie okna kontekstu do VRAM (poniżej 24 GiB → 4k, 24–48 GiB → 32k, od 48 GiB → 256k), zmienna <code>OLLAMA_CONTEXT_LENGTH</code> oraz uwaga o rosnącym koszcie pamięci, <a href="https://docs.ollama.com/context-length">docs.ollama.com/context-length</a>.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>Ollama docs — <code>PARAMETER num_ctx</code> (okno kontekstu modelu) w Modelfile oraz nadpisywanie parametrów Modelfile opcjami podanymi w locie przez API, <a href="https://github.com/ollama/ollama/blob/main/docs/modelfile.mdx#valid-parameters-and-values">docs/modelfile.mdx</a>.&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>llama.cpp — kroki dodania wsparcia nowej architektury (skrypty konwersji w Pythonie + kod C++ + testy CPU/CUDA/Metal), <a href="https://github.com/ggml-org/llama.cpp/blob/master/docs/development/HOWTO-add-model.md">docs/development/HOWTO-add-model.md</a>.&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p>Hugging Face transformers docs — Chat templating: różnica base vs instruct/chat, tokeny kontrolne, <code>apply_chat_template</code>, ryzyko złego formatu promptu, <a href="https://huggingface.co/docs/transformers/en/chat_templating">huggingface.co/docs/transformers/en/chat_templating</a>.&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:8">
<p>„Benchmark Data Contamination of Large Language Models: A Survey&quot;, przegląd problemu przecieku danych ewaluacyjnych do zbioru treningowego, <a href="https://arxiv.org/abs/2406.04244">arXiv:2406.04244</a>.&#160;<a href="#fnref:8" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>