Silnik basal 2.2: kalibracja na własnych danych
basal-calibrate w silniku 2.2 sprawdza na Twoich oznaczonych przykładach, czy pewność modelu znaczy to, co mówi, i wyznacza certyfikowane progi. Model decyduje sam tylko tam, gdzie cel błędu jest spełniony, a resztę przekazuje człowiekowi. Do tego porty FP8 i GGUF basal-omni-1.0-mini i max.
Model decyzyjny jest użyteczny tylko wtedy, gdy „90% pewności” znaczy 90% na Twoich danych. Kalibrację dostarczaną z modelami dopasowaliśmy na naszych danych. Na Twoich model może być pewny siebie inaczej, nawet gdy jest równie trafny.
Silnik basal 2.2 pozwala to sprawdzić i poprawić samodzielnie. basal-calibrate mierzy model na Twoich oznaczonych przykładach i wyznacza certyfikowane progi. Model decyduje sam tylko tam, gdzie cel błędu jest spełniony. Resztę przekazuje człowiekowi. Do tego wydajemy porty FP8 i GGUF basal-omni-1.0-mini i max.
Co znaczy „90% pewności”
Każdy model basal zwraca prawdopodobieństwo każdej dozwolonej odpowiedzi. W pytaniach act i tool podajesz cel błędu, na przykład "max_error": 0.01. Model działa sam tylko wtedy, gdy jego pewność osiąga próg certyfikowany dla tego celu. W przeciwnym razie oddaje decyzję człowiekowi.
Temperatury i progi są w pliku CALIBRATION.json dostarczonym z modelem. Dopasowaliśmy je na naszych danych. Na Twojej dziedzinie model może być pewny siebie inaczej. Wtedy próg z naszych danych przyjmuje za mało decyzji albo za dużo, łącznie z błędnymi.
Tego nie widać bez pomiaru. Dlatego pierwszy krok w 2.2 to raport: jak plik, którego dziś używasz, działa na Twoich oznaczonych danych. Hostowane API decyzyjne nie daje takiego kroku: jego pewność jest taka, jaka jest na Twoich danych. Model basal działa u Ciebie, więc możesz go skalibrować na swoich danych.
Kalibracja na własnych danych
Potrzebujesz pliku JSONL: jedno zapytanie /v1/systemone w wierszu, a przy każdym pytaniu poprawna odpowiedź w polu "gold". Wysyłaj zapytania dokładnie tak jak w produkcji: z tymi samymi opcjami, faktami i językiem stanu.
{"id": "t-17", "group": "customer-17", "state": "...",
"questions": {
"dept": {"type": "choice", "instructions": "...", "criteria": {"returns": "...", "it": "..."}, "gold": "returns"},
"late": {"type": "noul", "instructions": "...", "gold": "yes"},
"level": {"type": "score", "instructions": "...", "criteria": ["low", "mid", "high"], "gold": 2}}}basal-calibrate labelled.jsonl --model Remek/basal-omni-1.0-max --mode eager --report-only
basal-calibrate labelled.jsonl --model Remek/basal-omni-1.0-max --mode eager
basal-serve --model Remek/basal-omni-1.0-max --mode eager --calibration CALIBRATION.custom.jsonPierwsze polecenie tylko mierzy i niczego nie zapisuje. Drugie zapisuje plik CALIBRATION.custom.json, dopasowany tą samą metodą co pliki dostarczane z modelami. Trzecie uruchamia z nim serwer.
- Podział. Decyzje dzielą się na część do dopasowania (70%) i część kontrolną (30%). Decyzje jednej grupy, na przykład jednego klienta, zostają po tej samej stronie.
- Temperatury. Jedna na typ pytania (
choice,noul,score). Poprawiają to, jak pewność modelu odpowiada jego trafności na Twoich danych. - Certyfikowane progi. Próg dla celu 1% albo 5% to najniższa pewność, przy której górna granica błędu przyjętych decyzji (jednostronny 95% przedział Clopper–Pearson) nie przekracza celu. Jeśli takiej pewności nie ma, próg nie powstaje i basal-serve oddaje człowiekowi każdą taką decyzję.
- Kontrola. Część kontrolna, niewidziana przy dopasowaniu, pokazuje, ile decyzji plik przyjmuje automatycznie i z jakim błędem, obok pliku, którego używasz dziś.
Kalibruj z tym silnikiem, portem i kwantyzacją, które uruchamiasz w produkcji. Prawdopodobieństwa, a więc i progi, należą do nich. Kalibracja działa z każdym modelem basal-2.0 i basal-omni.
Cały proces krok po kroku, od oznaczonych przykładów do serwera, pokazuje ten film (7:16, polski lektor, napisy PL i EN). Jest też w Basal Lab: Pewność sprawdzona na Twoich danych.
Pomiar na nowej dziedzinie
Sprawdziliśmy to na basal-omni-1.0-mini (bf16, silnik 2.2, 16 października) i otwartym zbiorze typed-decisions (Apache-2.0). To syntetyczne decyzje nad rekordami JSON w czterech procesach: obsługa klienta, faktury, incydenty bezpieczeństwa i przebiegi agentów. Etykiety pochodzą z modelu nauczyciela. Model nie był na tych danych trenowany ani kalibrowany.
Kalibracja na części treningowej: 3 958 oznaczonych decyzji w 800 zapytaniach, do tego 596 pytań classify i 1 600 twierdzeń verify. Pomiar na części kontrolnej zbioru testowego: 172 decyzje choice, 184 tak/nie i 237 na skali.
| Na zbiorze testowym | Plik dostarczony z modelem | Plik po kalibracji na zbiorze treningowym |
|---|---|---|
| ECE: choice / tak-nie / skala | 0,268 / 0,106 / 0,104 | 0,083 / 0,073 / 0,052 |
max_error: 0.01: automatycznie i błąd | 12,6%, z tego 8,0% błędnych | 0% (nic nie spełnia celu) |
max_error: 0.05: automatycznie i błąd | 54,3%, z tego 21,4% błędnych | 3,7%, bez błędów |
verify: twierdzenia przy max_error: 0.01 | brak progu dla zadania | 54,8%, bez błędów (górna granica 1,1%) |
- Plik dostarczony nie trzyma celu na tej dziedzinie. Ustawienie „1%” przyjęłoby automatycznie jedną decyzję na osiem, a 8,0% z nich byłoby błędnych. Ustawienie „5%” przyjęłoby ponad połowę decyzji przy 21,4% błędów. Na naszych danych kalibracyjnych ten sam plik cel spełnia.
- Po kalibracji ECE spada w każdym typie: w choice ponad trzykrotnie, na skali o połowę, w tak/nie o ok. 30%. Temperatury rosną (choice z 1,14 do 2,67), bo na tych rekordach model jest zbyt pewny siebie.
- Prawie nic nie trafia do automatu, i to jest poprawna odpowiedź. Trafność mini na tych danych to 0,57 / 0,80 / 0,67 (choice / tak-nie / skala), wobec etykiet z szumem. Przy takiej trafności żaden próg nie spełnia celu 1%, więc decyzje trafiają do człowieka.
- Tam, gdzie model jest trafny, automatyzacja zostaje. Na twierdzeniach
verifymini ma 95% trafności. Próg dopasowany na zbiorze treningowym przyjmuje automatycznie 54,8% twierdzeń zbioru testowego, bez żadnego błędu.
Wszystkie liczby dotyczą części kontrolnej zbioru testowego, niewidzianej przy kalibracji. Opis i polecenia: CALIBRATION.md.
Co jeszcze w silniku 2.2
- Progi zadań z Twoich etykiet. Oznaczone pytania
classify,verifyiextractcertyfikują poleautomatedw odpowiedziach tych zadań, tą samą metodą co progi decyzji. Bez takiego progu pole ma wartośćnull. extractraportujeautomateddla każdego pola, tak jak odpowiedźclassifyi każde twierdzenie zverify.- Kilkadziesiąt etykiet na start. Gdy typ ma mniej niż 50 decyzji do dopasowania, ale co najmniej 10, jego temperatura łączy się z dostarczoną proporcjonalnie do liczby etykiet. 50 decyzji do dopasowania, czyli ok. 72 oznaczone, dopasowuje ją w pełni.
- Raport tak, jak serwuje basal-serve. Widzisz, ile decyzji dzisiejszy plik przyjmuje automatycznie na Twoich danych i z jakim błędem, dla każdego typu przy progu, który serwer naprawdę stosuje.
- Plik zna swój model. Pole
fitted_onzapisuje model i jego rewizję na Hugging Face. basal-serve ostrzega, gdy plik pochodzi z innego modelu albo innej rewizji, a z--strict-calibrationodmawia startu. - Poprawka. Luźniejszy cel (5%) nie zachowuje już ostrzejszego progu niż cel 1%. Wcześniej przeszukiwanie mogło zatrzymać się za wcześnie i przy 5% automatyzować mniej niż przy 1%.
Reszta bez zmian. Pozostałe zapytania przechodzą przez ten sam kod co w v2.1.0. Wagi modeli się nie zmieniają. Pełna lista: WHATS_NEW.md.
FP8 i GGUF dla basal-omni-1.0-mini i max
Cztery nowe repozytoria z tym samym modelem i tym samym API, w mniejszych formatach. Wszystkie czytają tylko tekst; do obrazów i dźwięku służą modele bf16.
- FP8 przez vLLM. Mniej pamięci (mini 12 GB zamiast 16 GB, max 14 GB zamiast 24 GB) i 1,4–1,5 raza więcej decyzji na sekundę niż bf16 w vLLM: mini 23,2 wobec 15,4, max 8,7 wobec 5,6 (jedno RTX PRO 6000, 16 zapytań naraz, jedno pytanie o stan ok. 1 500 tokenów). Wymaga GPU Ada, Hopper albo Blackwell.
- GGUF Q8_0 i Q6_K przez llama.cpp albo Ollama. Działają na GPU NVIDIA, na Macu z Apple Silicon i na CPU. mini Q8_0 działa na Macu z 16 GB pamięci; max Q8_0 z kontekstem 16 384 tokenów nie mieści się na Macu z 24 GB (działa z 8 192); użyj Maca z 32 GB albo pliku Q6_K.
| Port | Rozmiar | Ta sama odpowiedź co bf16 (2–10 opcji) | Trafność wobec bf16 | Automatycznie przy 1% / 5% |
|---|---|---|---|---|
| mini-FP8 · vLLM | 12 GB | 96,2% | −0,35 pkt | 41,9% / 63,5% (bf16: 41,7% / 77,6%) |
| max-FP8 · vLLM | 14 GB | 96,9% | −0,34 pkt | 45,4% / 82,5% (bf16: 47,2% / 83,0%) |
| mini Q8_0 · GGUF | 7,9 GB | 98,7% | −0,06 pkt | 42,4% / 78,3% |
| mini Q6_K · GGUF | 6,2 GB | 97,1% | +0,05 pkt | plik kalibracji Q8_0 |
| max Q8_0 · GGUF | 12,7 GB | 98,7% | −0,07 pkt | 47,9% / 82,5% |
| max Q6_K · GGUF | 9,8 GB | 97,6% | −0,11 pkt | plik kalibracji Q8_0 |
- Każdy port przechodzi bramkę portów basal: zgodność z bf16, zgodność tam, gdzie bf16 jest pewny, trafność w granicach 1 punktu i ECE. Zmienione decyzje to głównie niemal remisy dwóch opcji. Q5_K_M i Q4_K_M nie przeszły bramki, więc ich nie wydajemy.
- Każdy port ma własną kalibrację (
CALIBRATION.vllm.jsonalboCALIBRATION.gguf.json), dopasowaną na jego odczytach. Automatyzację mierzymy na zbiorze testowym kalibracji (8 560 decyzji). Przy GGUF obserwowany błąd wynosił 0,7% / 3,9% dla mini i 0,5% / 4,0% dla max. - Mac i Ollama. mini Q8_0 na Apple M4 Pro: ta sama odpowiedź co bf16 w 98,9% decyzji, 1,2 decyzji na sekundę. Przez Ollama 0.35: 98,0%.
- MLX na Macu z Apple Silicon. basal-omni-1.0-mini-MLX: 8,6 GB, ta sama odpowiedź co bf16 w 98,6% decyzji (2–10 opcji), 0,73 decyzji na sekundę (Apple M4 Pro, 24 GB), automatycznie 34% / 74% decyzji przy celu 1% / 5%; basal-omni-1.0-max-MLX: 13,6 GB, ta sama odpowiedź co bf16 w 98,9% decyzji (2–10 opcji), 0,25 decyzji na sekundę (Apple M4 Pro, 24 GB; przy 8 równoległych długich zapytaniach może zabraknąć pamięci), automatycznie 36% / 85% decyzji przy celu 1% / 5%; basal-omni-1.1-max-MLX: 13,6 GB, ta sama odpowiedź co bf16 w 98,4% decyzji (2–10 opcji), 0,27 decyzji na sekundę (Apple M4 Pro, 24 GB; przy 8 równoległych długich zapytaniach może zabraknąć pamięci), automatycznie 35% / 80% decyzji przy celu 1% / 5%. Tylko tekst.
- Dostępność. basal-omni-1.0-mini-FP8, basal-omni-1.0-max-FP8, basal-omni-1.0-mini-GGUF, basal-omni-1.0-max-GGUF.
Wyniki modeli w Werdykcie (mini 0,769, max 0,823) dotyczą wag bf16; porty nie są oceniane w nim osobno. Szczegóły: OMNI.md.
Ograniczenia
- Kalibracja nie poprawia trafności. Sprawia, że pewność modelu mówi prawdę. Model słaby na Twoich danych po kalibracji oddaje więcej decyzji człowiekowi.
- Cel 1% wymaga wielu etykiet. Kilkaset oznaczonych decyzji zwykle wystarcza na cel 5%. Cel 1% wymaga co najmniej 299 przyjętych decyzji bez błędu, w praktyce ok. 1 000 przykładów albo więcej. Przy mniejszej liczbie używaj nowych temperatur i progu 5% albo kieruj niepewne przypadki do człowieka.
- Progi dotyczą tego, na czym kalibrujesz. Obowiązują dla tej mieszanki typów pytań i promptów oraz dla Twoich etykiet. Gdy zmienia się proces albo dane, zmierz ponownie z
--report-only. - Porty czytają tylko tekst. W vLLM odpowiedź bliska remisu może się zmienić między przebiegami;
VLLM_BATCH_INVARIANT=1daje powtarzalne odpowiedzi kosztem ok. 23% decyzji na sekundę. mini-FP8 przy celu 5% automatyzuje mniej niż bf16. Ollama czyta najwyżej 20 opcji i 4 096 tokenów. - Zachowaj nadzór nad istotnymi decyzjami. Decyzje o poważnych skutkach dla ludzi wymagają kontroli człowieka.
Wkłady społeczności
basal jest otwarty. Ludzie budują na nim własne rozwiązania, a my włączamy ich pracę do silnika. Wcześniej, w basal 1.5, Paweł Kiszczak (@pawelkiszczak) przyniósł obsługę Apple Silicon (MLX, MPS) oraz llama.cpp i Ollama (PR #4), za co bardzo dziękujemy. Za wkład w 2.2 dziękujemy:
- Piotr Durlej (@pdurlej),
basal-export-gguf: konwertuje albo naprawia pliki GGUF tak, by ich tokenizer zgadzał się z oficjalnymi plikami -GGUF (PR #8). - Kuba Sołtys (@qooba),
--mode tpu: eksperymentalny backend na JAX / XLA, który uruchamia basal-2.0 na Google TPU (PR #15). - Michał Kardyś (@kardysm),
--mode strix: eksperymentalny tryb z kernelami Triton dla AMD Strix Halo, dla basal-1.5 i basal-2.0 (PR #14). - @lukaspoloki,
basal-viz: lokalna strona, która pokazuje każdy krok decyzji modeli basal-2.0 (architektura Llama); uruchamia ją polecenie o tej samej nazwie (PR #2).
Oba nowe backendy są eksperymentalne i utrzymuje je społeczność. Liczby w ich dokumentacji to pomiary ich autorów. Kod, zgłoszenia i propozycje zmian: github.com/rkinas/basal.
Jak zacząć
uv venv --python 3.12 --allow-existing ~/basal-env && source ~/basal-env/bin/activate
uv pip install torch==2.11.0 torchvision==0.26.0 --index-url https://download.pytorch.org/whl/cu128
uv pip install "basal[media] @ https://github.com/rkinas/basal/archive/refs/tags/v2.2.0.tar.gz"
basal-calibrate labelled.jsonl --model Remek/basal-omni-1.0-mini --mode eager --report-onlyuv pip install vllm==0.31.0 "basal @ https://github.com/rkinas/basal/archive/refs/tags/v2.2.0.tar.gz"
basal-serve --model Remek/basal-omni-1.0-max-FP8 --mode vllm --max-len 16384 --gpu-memory 0.9 --port 8000uv pip install "basal[gguf] @ https://github.com/rkinas/basal/archive/refs/tags/v2.2.0.tar.gz"
hf download Remek/basal-omni-1.0-mini-GGUF --local-dir basal-omni-1.0-mini-GGUF
basal-serve --model ./basal-omni-1.0-mini-GGUF --mode gguf --gguf basal-omni-1.0-mini-GGUF/basal-omni-1.0-mini-Q8_0.gguf --port 8000Silnik v2.2.0 jest na GitHubie: informacje o wydaniu. Na NVIDIA zbuduj llama-cpp-python z CUDA (opis w GGUF.md silnika); na Macu działa Metal. Opcje serwera, w tym --calibration: strona serwera inferencji.