Syntetyczne dane do trenowania i testów LLM: jak uniknąć „self-licking ice cream” efektu
Praktyczny przewodnik po generowaniu syntetycznych danych do trenowania i testów LLM: różnorodność, prompty, walidacja, wykrywanie artefaktów, miks z danymi realnymi i ochrona przed leakage.
1. Wprowadzenie: po co generować dane syntetyczne dla LLM i czym jest efekt „self-licking ice cream”
Duże modele językowe (LLM) potrzebują danych nie tylko do uczenia, ale też do rzetelnego sprawdzania jakości: czy poprawnie rozumieją instrukcje, trzymają się formatu, radzą sobie z nietypowymi pytaniami i czy zachowują się stabilnie w różnych warunkach. W praktyce często brakuje danych, które byłyby jednocześnie liczne, różnorodne, dobrze opisane i bezpieczne w użyciu. Wtedy pojawiają się dane syntetyczne: przykłady generowane (w całości lub częściowo) przez modele, reguły lub symulacje, zamiast pozyskiwane wprost od użytkowników czy z publicznych źródeł.
Dane syntetyczne nie są „zamiennikiem rzeczywistości”, lecz narzędziem do świadomego kształtowania zbioru treningowego i testowego. Pozwalają szybciej pokryć obszary, które w realnych danych występują rzadko, a mają duże znaczenie dla jakości i ryzyka. Jednocześnie niosą własne pułapki: mogą utrwalać styl, błędy i założenia modelu, który je wygenerował, oraz dawać złudnie dobre wyniki w testach.
Najczęstsze powody, dla których generuje się dane syntetyczne dla LLM:
- Skalowanie pokrycia — szybkie tworzenie wielu przykładów dla nowych funkcji (np. nowe formaty odpowiedzi, nowe typy zadań), gdy brakuje gotowych danych.
- Wypełnianie luk — dopisywanie przypadków brzegowych, rzadkich intencji i trudnych sytuacji, które realnie się zdarzają, ale są słabo reprezentowane w logach czy korpusach.
- Kontrola i etykietowanie — generowanie danych wraz z metadanymi (np. typ zadania, oczekiwany styl, poziom trudności), co ułatwia trenowanie i diagnozę błędów.
- Prywatność i zgodność — ograniczenie ryzyka ujawnienia danych osobowych lub treści poufnych przez pracę na danych, które nie pochodzą bezpośrednio od użytkowników.
- Testy regresji — budowanie powtarzalnych zestawów testowych, które można uruchamiać cyklicznie, by wykrywać pogorszenia po zmianach modelu lub promptów.
Warto odróżnić dwa główne zastosowania danych syntetycznych:
- Do trenowania — służą do kształtowania zachowania modelu (np. lepsze wykonywanie instrukcji). Kluczowe jest, by nie wprowadzać systematycznych zniekształceń i nie „przeuczyć” modelu na sztuczne wzorce.
- Do testów i ewaluacji — mają mierzyć jakość w sposób porównywalny w czasie. Kluczowe jest, by testy były niezależne od procesu generacji i nie premiowały „zgadywania stylu generatora”.
Tu dochodzimy do efektu „self-licking ice cream” (dosłownie: „lody liżące same siebie”) — sytuacji, w której system sam napędza przekonanie o swojej skuteczności, bo mierzy się i poprawia na podstawie danych, które sam wytwarza. W kontekście LLM oznacza to pętlę, w której:
- model (lub bardzo podobny model) generuje dane treningowe albo testowe,
- kolejna wersja modelu uczy się na tych danych,
- a następnie jest oceniana na testach, które również są syntetyczne i „w stylu” generatora,
- co daje wysokie wyniki, mimo że realna użyteczność i generalizacja mogą nie rosnąć (a czasem nawet spadać).
To zjawisko bywa podstępne, bo wygląda jak postęp: metryki idą w górę, a liczba przykładów rośnie. Problem w tym, że model może nauczyć się przede wszystkim artefaktów danych syntetycznych: preferowanych sformułowań, charakterystycznych skrótów myślowych, typowych schematów odpowiedzi czy uproszczonych założeń. W rezultacie poprawia się „trafianie w klucz odpowiedzi” właściwy dla generatora, a nie umiejętność radzenia sobie z autentyczną różnorodnością użytkowników i zadań.
Wprowadzenie danych syntetycznych ma więc sens tylko wtedy, gdy jest prowadzone świadomie: z myślą o tym, co dokładnie chcemy nimi osiągnąć, jakie ryzyka wnoszą oraz jak uniknąć zamkniętej pętli potwierdzania własnych założeń. Najważniejsze w tej dyskusji jest napięcie między skalą i kontrolą (zalety syntetyków) a realizmem i niezależnością pomiaru (warunek wiarygodnej jakości).
2. Źródła różnorodności danych syntetycznych: scenariusze, persony, domeny, języki, style i poziomy trudności
Różnorodność w danych syntetycznych nie polega na „większej liczbie przykładów”, tylko na szerszym pokryciu sytuacji użycia, w których model ma działać. Jeśli generator produkuje wciąż podobne pytania i podobne odpowiedzi, powstaje złudzenie jakości: wyniki rosną, ale model uczy się głównie rozpoznawać powtarzalny format, a nie rozwiązywać realne problemy. Dlatego różnorodność warto projektować w kilku niezależnych wymiarach, tak aby dane wymuszały inne zachowania modelu. Podczas szkoleń Cognity ten temat wraca regularnie – dlatego zdecydowaliśmy się go omówić również tutaj.
- Scenariusze — „co się dzieje” i jaki jest cel: pytanie faktograficzne, doradztwo, streszczenie, plan działania, analiza ryzyka, negocjacja, diagnostyka problemu, wsparcie klienta, tworzenie treści, kontrola zgodności z zasadami, itp. Scenariusz definiuje strukturę interakcji (np. jedno pytanie vs dialog), oczekiwany wynik i warunki brzegowe.
- Persony — „kto pyta” i „kto odpowiada”: poziom wiedzy użytkownika (laik, praktyk, ekspert), potrzeby (szybka odpowiedź vs uzasadnienie), ograniczenia (czas, budżet), a także rola systemu (asystent, recenzent, tutor, analityk). Persony pomagają unikać jednego, dominującego tonu i jednego poziomu szczegółowości.
- Domeny — „o czym” jest zadanie: obszary tematyczne i typy danych (teksty, liczby, procedury, reguły). Domeny wymuszają inne słownictwo, inne typy błędów i inne kryteria poprawności. Ważne jest też mieszanie domen „czystych” z problemami przekrojowymi (np. łączącymi analizę tekstu z elementami logiki lub planowania).
- Języki — „w jakim języku” i w jakiej odmianie: różne języki, warianty regionalne, rejestry (formalny/nieformalny), a także mieszanie języków w jednym kontekście. Różnorodność językowa to również różne sposoby wyrażania poleceń i pytań, nie tylko tłumaczenia tych samych przykładów.
- Style — „jak to jest napisane”: ton (neutralny, stanowczy, uprzejmy), format (lista, opis, dialog, instrukcja), gęstość informacji, użycie skrótów, specjalistyczna terminologia, a także obecność „szumu” (literówki, niepełne zdania, niejasne wymagania). Style są kluczowe, bo modele często nadmiernie dopasowują się do jednego, eleganckiego wzorca generacji.
- Poziomy trudności — „jak łatwo się pomylić”: od zadań prostych po złożone, wieloetapowe i z ograniczeniami. Trudność może wynikać z długości kontekstu, liczby warunków, konieczności rozróżniania podobnych pojęć, konfliktujących wymagań, wieloznaczności lub potrzeby odmowy. Świadome stopniowanie trudności ułatwia pokrycie zarówno podstawowych kompetencji, jak i przypadków brzegowych.
W praktyce najlepsze efekty daje łączenie wymiarów: ten sam typ zadania w wielu domenach, z różnymi personami i stylami, oraz na kilku poziomach trudności. Dzięki temu dane syntetyczne przestają być jednolitą „produkowaną taśmowo” masą, a zaczynają przypominać zróżnicowany rozkład sytuacji, które spotyka się w realnym użyciu modeli.
3. Projektowanie promptów i kontrola generacji: instrukcje, ograniczenia, parametry oraz multi-model/multi-pass
Generowanie danych syntetycznych dla LLM nie polega na „napisaniu promptu i kliknięciu uruchom”. Żeby zbiór był użyteczny (do trenowania, fine-tuningu lub testów), trzeba zaprojektować sposób generacji tak, aby dane były: (1) zgodne ze specyfikacją, (2) zróżnicowane, (3) kontrolowane pod kątem formatu, (4) możliwe do powtórzenia i wersjonowania. W praktyce osiąga się to poprzez połączenie: instrukcji (co ma powstać), ograniczeń (czego nie wolno i w jakiej formie), parametrów losowości oraz podejścia multi-model/multi-pass (wiele modeli lub wiele przebiegów z różnymi rolami).
Instrukcje: „co” generujemy i po co
Dobre instrukcje są operacyjne: precyzują typ danych i intencję. Zamiast „wygeneruj pytania”, lepiej opisać: rodzaj zadania, zakres, poziom trudności, docelowy format oraz kryteria poprawności. Instrukcje warto budować tak, aby model miał jasne kryterium sukcesu.
- Specyfikacja rekordu: co jest wejściem, co jest wyjściem, jakie pola są obowiązkowe.
- Cel użytkowy: trening (pokrycie przypadków) vs test (stabilne, jednoznaczne odpowiedzi).
- Zakres tematyczny: słownik pojęć, granice domeny, preferowane konwencje.
- Pożądane zachowanie: np. „odpowiedź musi być weryfikowalna w tekście wejściowym”, „nie dodawaj faktów spoza danych”.
Ograniczenia: „jak” i „czego nie wolno”
Ograniczenia chronią przed rozjechaniem się jakości oraz przed produkowaniem danych, które później trudno filtrować. Najczęściej mają postać reguł formatu, limitów i zakazów. W kontekście ryzyka „self-licking ice cream” ważne jest, by ograniczenia nie wymuszały jednego, modelowego stylu wypowiedzi (np. przesadnie uporządkowanych odpowiedzi), bo wtedy syntetyki zaczynają przypominać same siebie.
- Kontrakty formatu: JSON/CSV, stałe klucze, typy pól, maksymalna długość, zakaz markdown.
- Zakazy treści: brak meta-komentarzy („jako model AI…”), brak ujawniania promptu, brak instrukcji dla użytkownika jeśli generujemy „gold answer”.
- Ograniczenia dowodowe: „odpowiadaj wyłącznie na podstawie podanego kontekstu”, „jeśli brak danych — zwróć UNKNOWN”.
- Kontrola dystrybucji: docelowe proporcje typów przypadków (np. 30% negatywnych, 20% wieloznacznych), realizowane przez parametryzację promptu.
Parametry generacji: sterowanie losowością i powtarzalnością
Parametry (np. temperatura, top-p, ograniczenia długości) służą do balansowania między różnorodnością a stabilnością. Do testów zwykle dąży się do większej deterministyczności, a do treningu — do kontrolowanej różnorodności. Kluczowe jest, aby parametry były spójne w ramach wersji zbioru i zapisane razem z promptem.
| Cel | Ustawienia preferowane | Efekt |
|---|---|---|
| Test / benchmark | niższa losowość, krótsze odpowiedzi, silny kontrakt formatu | większa powtarzalność i mniejsza liczba „odjazdów” |
| Trening / augmentacja | umiarkowana losowość, kontrolowane zróżnicowanie stylu, limity na rozwlekłość | większe pokrycie wariantów przy zachowaniu reguł |
| Eksploracja przypadków | wyższa losowość + twarde walidatory formatu | nowe przypadki brzegowe, ale rośnie potrzeba filtracji |
Szablony i parametryzacja promptów
Najpraktyczniejsze są prompty szablonowe z „pokrętłami” (parametrami), które można systematycznie przemiatać: typ zadania, długość, styl, liczba kroków rozumowania opisana jako wymóg struktury (np. „podaj uzasadnienie w 2 zdaniach”), poziom formalności, język. Dzięki temu generacja jest skalowalna i mniej przypadkowa.
Warto oddzielać:
- prompt systemowy (reguły, format, zakazy),
- prompt zadaniowy (specyfikacja rekordu),
- zmienne (np. temat, długość, styl, klasa trudności).
{
"system": "Generuj rekordy w JSON bez markdown. Bez meta-komentarzy. Jeśli nie da się spełnić wymagań, zwróć ERROR.",
"task": "Wygeneruj 1 przykład zadania typu: {task_type}. Zwróć pola: input, expected_output, tags.",
"vars": {
"task_type": "klasyfikacja intencji",
"language": "pl",
"style": "neutralny",
"max_len": 80
}
}
Multi-pass: kilka przebiegów z różnymi rolami
Multi-pass to podejście, w którym jedna generacja jest rozbita na etapy, aby lepiej kontrolować wynik. Zamiast oczekiwać, że model „od razu” stworzy idealny rekord, można: (1) wygenerować surowy przypadek, (2) doprecyzować go, (3) sprawdzić zgodność z regułami, (4) naprawić błędy. To pozwala zwiększyć zgodność bez konieczności nadmiernego usztywniania pierwszego promptu.
- Generate → Refine: najpierw warianty, potem ujednolicenie do kontraktu.
- Generate → Critique → Repair: model (lub drugi przebieg) wskazuje naruszenia reguł, a kolejny przebieg je usuwa.
- Plan → Execute: osobny krok na zaplanowanie struktury rekordu, osobny na wypełnienie treścią.
Multi-model: różne modele do różnych zadań
Multi-model polega na użyciu różnych modeli w pipeline: jedne generują treść, inne ją weryfikują lub parafrazują. Celem nie jest „większa ilość”, tylko zmniejszenie autokorelacji stylu i ograniczenie powtarzalnych artefaktów. Typowy podział ról:
- Model generator: tworzy przykład zgodnie ze specyfikacją.
- Model redaktor: poprawia format, skraca, usuwa schematyczne frazy, ujednolica pola.
- Model krytyk: ocenia zgodność z regułami i wykrywa oczywiste błędy logiczne lub brak pokrycia wymagań.
Kontrola „modelese”: jak nie wymusić jednego, sztucznego stylu
Jeśli prompt zbyt mocno narzuca strukturę i ton, zbiór szybko nabiera „sygnatury” modelu: podobne wstępy, podobne podsumowania, te same łączniki. To utrudnia generalizację i zwiększa ryzyko efektu, w którym model uczy się rozpoznawać własny styl zamiast zadania. W projektowaniu promptów pomocne są:
- Jawne zakazy stereotypowych fraz (np. wstępów i podsumowań), jeśli nie są częścią domeny.
- Losowanie wariantów instrukcji (kilka równoważnych szablonów) zamiast jednego „kanonicznego” promptu.
- Ograniczenia na długość i „bez lania wody”, aby nie produkować generycznych wyjaśnień.
- Parafraza kontrolowana: ten sam przypadek w kilku realizacjach językowych, ale z zachowaniem sensu i formatu pól.
Minimalny zestaw praktyk operacyjnych
- Traktuj prompt jak kod: wersjonuj, opisuj parametry, zapisuj konfigurację generacji.
- Buduj kontrakty: format i reguły muszą być sprawdzalne automatycznie.
- Stosuj pipeline: generowanie, korekta, krytyka/naprawa jako osobne kroki.
- Unikaj jednego szablonu: kilka równoległych promptów zmniejsza jednolitość i artefakty.
4. Walidacja jakości i zgodności: kryteria, automatyczne testy, ocena przez modele i audyt człowieka
Dane syntetyczne dla LLM kuszą skalą i szybkością, ale bez walidacji łatwo wprowadzić do pipeline’u treści niepoprawne, niezgodne z wymaganiami albo nieprzydatne treningowo. W praktyce walidacja ma dwa cele: (1) sprawdzić, czy przykład spełnia specyfikację (format, zakres, polityki), oraz (2) czy wnosi wartość merytoryczną (prawidłowość, trudność, brak oczywistych błędów). Najlepiej działa podejście warstwowe: od prostych reguł i testów automatycznych, przez ocenę modelową, po selektywny audyt człowieka. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — bo łatwo „przepuścić” syntetyki, które wyglądają wiarygodnie, ale nie dowożą jakości ani zgodności.
Kryteria akceptacji: co mierzyć, zanim zacznie się mierzyć „jakość”
Walidację warto oprzeć o jawne, zoperacjonalizowane kryteria. Bez nich „dobre” i „złe” przykłady mieszają się w jednym worku, a sygnał treningowy staje się losowy.
- Zgodność ze specyfikacją zadania: czy przykład faktycznie testuje/trenuje to, co deklarujesz (intencja, typ zadania, dozwolone narzędzia, wymagany styl odpowiedzi).
- Poprawność merytoryczna: brak błędów faktograficznych, rachunkowych i logicznych; spójność odpowiedzi z pytaniem i danymi wejściowymi.
- Jednoznaczność i kompletność: czy polecenie jest wystarczająco precyzyjne, czy oczekiwany wynik da się zweryfikować.
- Jakość językowa i format: poprawna gramatyka, brak artefaktów, zgodność z wymaganym schematem (np. JSON, lista kroków, cytowania).
- Bezpieczeństwo i zgodność polityk: brak treści zabronionych, danych wrażliwych, instrukcji niebezpiecznych; respektowanie ograniczeń domenowych (np. brak porad medycznych bez zastrzeżeń).
- Użyteczność treningowa: odpowiedni poziom trudności, brak oczywistej „podpowiedzi” w treści, sensowna różnorodność (bez zalewania datasetu wariantami tego samego przykładu).
Testy automatyczne: tanie filtry o wysokim zwrocie
Automatyczne testy powinny usuwać „śmieci” zanim trafią do droższych etapów. Ich przewaga to powtarzalność i łatwość uruchamiania na dużej skali. Typowo obejmują:
- Walidację schematu i formatu: JSON Schema, regexy, kontrola pól obowiązkowych, długości, dozwolonych wartości.
- Testy spójności: czy odpowiedź odnosi się do danych wejściowych (np. wszystkie wymagane elementy są uwzględnione), czy nie ma sprzeczności wewnętrznych.
- Testy deterministyczne dla zadań z „kluczem”: obliczenia, parsowanie, transformacje tekstu, proste zadania logiczne – wszystko, co da się sprawdzić programowo.
- Sanity-checki językowe: wykrywanie pustych odpowiedzi, nadmiaru powtórzeń, nadmiernej długości, śladów promptu w odpowiedzi.
- Filtrowanie zgodności: słowniki i klasyfikatory dla zakazanych kategorii (w tym PII), wykrywanie linków/fragmentów, które łamią zasady datasetu.
| Warstwa walidacji | Co wykrywa najlepiej | Typowy koszt | Ryzyko |
|---|---|---|---|
| Reguły/schematy | Format, braki pól, oczywiste naruszenia | Niski | Fałszywe negatywy dla subtelnych błędów |
| Testy programowe | Rachunki, transformacje, zgodność z „kluczem” | Niski–średni | Ograniczone do zadań mierzalnych |
| Ocena modelowa | Semantyka, spójność, styl, policy compliance | Średni | Stronniczość i błędy oceniającego modelu |
| Audyt człowieka | Subtelne błędy, intencja, „czy to ma sens” | Wysoki | Niespójność między oceniającymi |
Ocena przez modele: „LLM jako sędzia” z jasnymi regułami gry
Modelowa ocena jakości jest użyteczna, gdy nie da się łatwo napisać testu deterministycznego (np. streszczenia, argumentacja, odpowiedzi dialogowe). Żeby ograniczyć uznaniowość, warto projektować ją jak pomiar, a nie opinię:
- Jawne rubryki: lista kryteriów i skala (np. 1–5) dla: zgodności z instrukcją, poprawności, kompletności, stylu, bezpieczeństwa.
- Ocena oparta o dowody: wymaganie wskazania, który fragment wejścia uzasadnia ocenę lub gdzie jest błąd (ułatwia audyt).
- Gating zamiast rankingów: progi akceptacji (pass/fail) dla krytycznych kryteriów, a dopiero potem oceny „miękkie”.
- Odrębne role: inny prompt dla „recenzenta zgodności”, inny dla „recenzenta merytoryki” – zmniejsza mieszanie kryteriów.
- Kalibracja: porównanie decyzji modelu do niewielkiego, ręcznie ocenionego zestawu referencyjnego i korekta rubryk/progów.
W praktyce LLM-sędzia najlepiej sprawdza się do: (a) selekcji spośród wielu kandydatów, (b) wychwytywania oczywistych naruszeń instrukcji, (c) wstępnego „screeningu” jakości językowej. Nie powinien być jedynym źródłem prawdy dla kryteriów wymagających niezależnej wiedzy lub wysokiej precyzji.
Audyt człowieka: precyzja tam, gdzie automaty nie domykają ryzyka
Audyt manualny jest kosztowny, więc powinien być celowany. Najczęściej obejmuje próbki losowe (kontrola procesu) oraz próbki „podejrzane” wytypowane przez testy i ocenę modelową (kontrola ryzyka). Kluczowe elementy skutecznego audytu:
- Instrukcja oceny: krótka karta zasad z przykładami błędów i minimalnym standardem akceptacji.
- Podwójne etykietowanie: część próbek oceniana przez dwóch audytorów; rozbieżności służą do doprecyzowania rubryk.
- Tagowanie przyczyn odrzutu: kody błędów (np. „niezgodność z instrukcją”, „błąd faktograficzny”, „niejednoznaczne polecenie”). To tworzy pętlę poprawy generatora i filtrów.
- Kontrola spójności: okresowe sprawdzanie zgodności między audytorami (nie tylko „ile odrzucono”, ale dlaczego).
Minimalny „quality gate” jako pipeline
Praktyczna walidacja zwykle wygląda jak bramka wieloetapowa, w której każdy etap redukuje wolumen i podnosi średnią jakość:
- Etap 1: schemat/format + szybkie filtry treści (odrzut natychmiastowy).
- Etap 2: testy programowe tam, gdzie możliwe (odrzut lub automatyczna korekta tylko dla bezpiecznych przypadków, np. formatowania).
- Etap 3: ocena modelowa wg rubryk (akceptacja, odrzut, lub kolejka do audytu).
- Etap 4: audyt człowieka na próbkach losowych i wysokiego ryzyka (zatwierdzenie lub oznaczenie do regeneracji).
# Pseudokod: przykładowy przepływ walidacji
for ex in generated_examples:
if not validate_schema(ex):
reject(ex, reason="schema")
continue
if contains_policy_violations(ex):
reject(ex, reason="policy")
continue
if has_deterministic_answer(ex) and not check_answer(ex):
reject(ex, reason="wrong_answer")
continue
score = llm_judge(ex, rubric=R)
if score.critical_fail:
reject(ex, reason="judge_fail")
elif score.borderline:
queue_for_human_audit(ex)
else:
accept(ex)
Taki układ nie rozwiązuje wszystkich problemów sam w sobie, ale stabilizuje jakość: przykłady przechodzą przez te same bramki, a decyzje (i powody decyzji) są mierzalne i audytowalne.
5. Wykrywanie artefaktów i degradacji: powtarzalność, sygnatury modelu, „modelese”, halucynacje i duplikaty
Dane syntetyczne potrafią szybko „zjechać” jakościowo: zamiast zwiększać pokrycie przypadków, zaczynają wzmacniać nawyki generatora, powielać te same schematy i wprowadzać błędy, które wyglądają wiarygodnie. W tej sekcji chodzi o wczesne wykrycie artefaktów (charakterystycznych śladów generowania) oraz degradacji (spadku różnorodności, jakości i zgodności), zanim takie dane trafią do trenowania lub testów.
Najczęstsze klasy problemów
- Powtarzalność – te same struktury dialogu, identyczne szablony odpowiedzi, podobne przykłady i argumenty, „bezpieczne” uogólnienia.
- Sygnatury modelu – rozpoznawalne frazy i nawyki stylistyczne (np. nadmiar zastrzeżeń, charakterystyczne przejścia, uporczywe listy kroków).
- „Modelese” – język „pod model”: poprawny, ale nienaturalny, przesadnie uporządkowany, pozbawiony lokalnych idiomów, z nadmierną meta-komunikacją („Oto odpowiedź…”, „Podsumowując…”).
- Halucynacje – fałszywe fakty, zmyślone źródła, nieistniejące zależności; szczególnie groźne w danych referencyjnych (QA, streszczenia, instrukcje).
- Duplikaty – literalne kopie, near-duplicates (parafrazy minimalne), klony strukturalne (to samo „rusztowanie” z podmienionymi nazwami/liczbami).
Szybka diagnostyka: co mierzyć i co to sygnalizuje
| Symptom | Jak to zwykle wygląda | Dlaczego to szkodzi | Sygnał ostrzegawczy (heurystyka) |
|---|---|---|---|
| Powtarzalność | Wiele rekordów zaczyna się/kończy identycznie; te same schematy punktów | Model uczy się formy zamiast treści; spada pokrycie przypadków brzegowych | Wysoki udział powtarzających się n-gramów; niska entropia długości/struktur |
| Sygnatury modelu | Stałe frazy, „uprzejme” wstępy, nadmiar disclaimers | Testy stają się zbyt łatwe dla podobnych modeli; ryzyko „self-licking” w ewaluacji | Częste wystąpienia fraz-znaczników; nietypowo wysoka formalność |
| Modelese | Nienaturalnie gładki tekst, przesadne uporządkowanie, brak idiomów | Spada realizm danych; gorsza generalizacja na tekst „ludzki” i domenowy | Niska różnorodność leksykalna; wysoka regularność składni i rytmu |
| Halucynacje | Pewny ton przy błędach; zmyślone fakty, cytaty, parametry | Wprowadza błędne sygnały treningowe i fałszywe etykiety | Sprzeczności wewnętrzne; brak zgodności z regułami zadania; „źródła” bez weryfikacji |
| Duplikaty | Tekst identyczny lub prawie identyczny; te same przykłady z drobnymi zmianami | Zawyża metryki, obniża efektywny rozmiar zbioru, zwiększa leakage | Wysokie podobieństwo embeddingowe; stabilne shingle-hashe |
Artefakty stylistyczne: jak rozpoznać „generator pisze generatorowo”
Artefakty rzadko są pojedynczym błędem; częściej to konstelacja nawyków. Typowe oznaki „modelese” i sygnatur:
- Meta-narracja: częste „Oto…”, „Poniżej…”, „W skrócie…”, „Zacznijmy od…”.
- Symetryczne formatowanie: niemal każdy rekord ma identyczne akapity i listy o stałej długości.
- Bezpieczna ogólność: unikanie konkretów, uśrednianie, rozmyte sformułowania („zależy”, „warto rozważyć”).
- Jednolity ton: brak rejestrów językowych, brak potoczności w miejscach, gdzie jest naturalna.
W danych testowych te cechy są szczególnie ryzykowne: test zaczyna mierzyć „rozpoznanie stylu generatora”, a nie kompetencję modelu.
Duplikaty i near-duplicates: kiedy „więcej danych” nie znaczy „więcej informacji”
Duplikacja w syntetykach pojawia się w trzech warstwach:
- Duplikat literalny: identyczny tekst/rekord.
- Near-duplicate: drobna parafraza, podmienione liczby/nazwy, to samo znaczenie.
- Duplikat strukturalny: inne słowa, ale ten sam szkielet argumentacji, te same kroki i przykłady w tej samej kolejności.
Praktycznie: literalne duplikaty łatwo usunąć, ale near-duplicates i duplikaty strukturalne mogą „przepompować” jeden wzorzec na tysiące rekordów, obniżając realną różnorodność. W efekcie model uczy się skrótów, a nie reguł.
Halucynacje: od „niewinnych” do toksycznych dla etykiet
Halucynacje w danych syntetycznych są groźne nie tylko jako błędy merytoryczne. Najbardziej szkodliwe są sytuacje, gdy halucynacja staje się częścią etykiety (np. „poprawna odpowiedź”, „gold summary”, „ground truth”). Wtedy błąd jest trenowany jako prawda.
- Halucynacje faktów: zmyślone parametry, daty, definicje, zależności.
- Halucynacje źródeł: nieistniejące cytaty, dokumenty, linki, „badania”.
- Halucynacje reguł zadania: generator łamie ograniczenia (format, długość, zakazy), ale robi to konsekwentnie i „ładnie”.
W syntetykach „pewność tonu” nie jest sygnałem jakości; dlatego wykrywanie halucynacji powinno opierać się na spójności wewnętrznej i zgodności z założeniami zadania, a nie na stylu.
Minimalny zestaw kontroli (bez rozbudowanej infrastruktury)
- Statystyki powierzchniowe: rozkład długości, udział list, nagłówków, cytowań; anomalie często wskazują na szablonizację.
- Wykrywanie duplikatów: hashowanie po normalizacji + podobieństwo na shinglach lub embeddingach (próg do odrzutu/klastrów).
- Detekcja fraz-sygnatur: lista zakazanych/niepożądanych zwrotów oraz ich częstość w korpusie.
- Kontrole spójności: proste reguły (np. zgodność formatu JSON, liczba pól, poprawność enumeracji) oraz wykrywanie sprzeczności (np. odpowiedź przeczy instrukcji).
Krótki przykład: szybkie flagowanie powtórzeń i podobieństwa
import re
from collections import Counter
def normalize(t: str) -> str:
t = t.lower().strip()
t = re.sub(r"\s+", " ", t)
t = re.sub(r"\d+", "<num>", t)
return t
def top_ngrams(texts, n=4, k=20):
c = Counter()
for t in texts:
w = normalize(t).split()
for i in range(len(w)-n+1):
c[tuple(w[i:i+n])] += 1
return c.most_common(k)
# texts = [...] # lista rekordów
# print(top_ngrams(texts, n=4, k=20))
To nie zastępuje pełnej walidacji, ale szybko ujawnia „szablonowe” frazy i nienaturalnie częste sekwencje, które są typowe dla powtarzalności oraz sygnatur modelu.
Interpretacja wyników: kiedy reagować
Nie każdy artefakt wymaga natychmiastowego odrzutu danych. Kluczowe jest rozróżnienie:
- Artefakt jako kosmetyka (np. sporadyczne meta-zwroty) vs artefakt systemowy (ten sam szkielet w dużej części zbioru).
- Błąd w treści (halucynacja faktu) vs błąd w etykiecie (halucynacja „golda”) — ten drugi jest zwykle znacznie groźniejszy.
- Duplikacja lokalna (kilka podobnych rekordów) vs duplikacja masowa (klastry setek przykładów o wysokim podobieństwie).
W praktyce warto traktować wykryte klastry powtórzeń, sygnatur i near-duplicates jako sygnał do kuracji: ograniczenia generatora, lepsza różnorodność źródeł, a przede wszystkim usunięcie tego, co zaniża efektywną informację w zbiorze.
6. Mieszanie danych syntetycznych z prawdziwymi: proporcje, ważenie, sampling oraz strategia kuracji
Dane syntetyczne są świetne do szybkiego zwiększania pokrycia przypadków, których brakuje w danych z życia (rzadkie intencje, nietypowe formaty, kontrolowane błędy, edge-case’y). Dane prawdziwe zwykle lepiej oddają dystrybucję produkcyjną: naturalny język, niejednoznaczności, szum, kontekst i realne ograniczenia. W praktyce najbezpieczniejsze podejście to nie „zastąpić” jedne drugimi, tylko mieszać je tak, aby syntetyki uzupełniały luki, a realne dane kotwiczyły model w rzeczywistości.
Proporcje: jak dużo syntetyków to „za dużo”?
Nie ma uniwersalnego procentu, ale są typowe role, które sugerują sensowne zakresy. Im bardziej syntetyczne dane przypominają wyłącznie „idealne” odpowiedzi modelu, tym większe ryzyko dryfu w stronę sztucznej dystrybucji (w tym efektu „self-licking ice cream”). Dlatego proporcję warto dobierać do celu:
| Zastosowanie | Rola danych syntetycznych | Praktyczna wskazówka dot. udziału |
|---|---|---|
| Uzupełnianie brakujących klas / intencji | Wyrównanie long tail | Dodawaj syntetyki lokalnie (tylko dla braków), zamiast podnosić udział w całym korpusie |
| Uczenie formatów (JSON, narzędzia, schematy) | Pokrycie wariantów struktury i walidacji | Może być wyższy udział, ale z twardymi regułami poprawności i minimalizacją „ładnego” języka |
| Stres-testy i odporność (adversarial, błędy użytkownika) | Symulacja trudnych wejść | Trzymaj jako osobny strumień treningowy lub osobne epoki; nie musi dominować w mieszance |
| Podstawowa jakość językowa / styl | Słaby kandydat na syntetyki | Preferuj dane prawdziwe; syntetyki traktuj jako dodatki, nie fundament |
Najczęstszy błąd to duży, jednorodny zastrzyk syntetyków „o podobnym zapachu” (ten sam styl, długość, sposób argumentacji), który statystycznie przytłacza dane realne. Bezpieczniej jest utrzymywać syntetyki jako celowany suplement, a nie masowy zamiennik.
Ważenie: syntetyki nie muszą mieć takiej samej „siły” jak realne
Mieszanka nie jest binarna (syntetyczne vs prawdziwe). Możesz sterować wpływem przykładów przez wagi, np. w zależności od:
- Pochodzenia: realne przykłady z większą wagą, syntetyczne z mniejszą.
- Pewności jakości: syntetyki po silniejszej walidacji lub z wieloetapowej generacji mogą mieć wagę wyższą niż „surowe”.
- Rzadkości: przykłady z long tail dostają większą wagę, aby model ich nie ignorował.
- Kosztu błędu: scenariusze krytyczne (np. bezpieczeństwo, zgodność z polityką) mogą być ważone wyżej niezależnie od źródła.
Ważenie jest często prostsze i stabilniejsze niż agresywne manipulowanie proporcjami w całym zbiorze: pozwala utrzymać różnorodność bez „zalania” treningu syntetykami.
Sampling: jak pobierać przykłady, by nie wypaczyć dystrybucji
Sampling to praktyczny mechanizm realizacji strategii mieszania. Zamiast wrzucać wszystko do jednego worka i tasować, warto budować strumienie (np. realne:ogólne, realne:trudne, syntetyczne:formaty, syntetyczne:edge-case) i kontrolować ich udział w batchach. Pomaga to:
- utrzymać pokrycie rzadkich przypadków w każdej epoce,
- unikać dominacji pojedynczego typu danych,
- łatwiej diagnozować regresje (wiesz, który strumień „zrobił różnicę”).
W praktyce często sprawdza się mieszanie warstwowe: osobno utrzymujesz rozkład z danych realnych (żeby nie odjechać od produkcji), a syntetykami dopalasz konkretne braki.
// Pseudokod: sampling warstwowy (proporcje strumieni w batchach)
streams = {
"real_main": 0.60,
"real_hard": 0.15,
"syn_format": 0.15,
"syn_edge": 0.10
}
for step in training:
batch = []
for name, p in streams:
batch += sample(name, size = round(p * BATCH_SIZE))
train(batch)Strategia kuracji: syntetyki jako „kontrolowana domieszka”
Najbardziej opłacalne jest traktowanie danych syntetycznych jak komponentu, który wymaga kuracji podobnej do danych realnych, tylko z innym profilem ryzyka. W sekcji mieszania kluczowe są cztery praktyki:
- Kuracja celowana: generuj i dodawaj syntetyki tylko tam, gdzie masz mierzalny brak (pokrycie intencji, formatów, języków, poziomów trudności), zamiast „więcej danych = lepiej”.
- Odchudzanie i deduplikacja: syntetyki są tanie, więc łatwo przesadzić z ilością. Lepiej trzymać mniej, ale bardziej zróżnicowanych przykładów.
- Balans stylu: jeśli syntetyki mają zbyt jednolity styl, wprowadzają artefakty. Mieszaj je z realnymi „ziarnami” (np. realny prompt + syntetyczne odpowiedzi lub odwrotnie) tylko wtedy, gdy wspiera to cel i nie psuje dystrybucji.
- Zasada kotwicy: utrzymuj stały, wysokiej jakości rdzeń danych realnych jako odniesienie; syntetyki powinny go wzmacniać, nie zastępować.
W efekcie dobra mieszanka to taka, w której dane prawdziwe definiują „jak świat wygląda”, a dane syntetyczne dopowiadają „co model ma umieć, nawet jeśli zdarza się rzadko”.
7. Separacja train/dev/test i zapobieganie leakage: zasady podziału, wersjonowanie, śledzenie pochodzenia danych
W syntetycznych zbiorach dla LLM ryzyko leakage (przecieku informacji między zbiorami) jest szczególnie wysokie: te same wzorce, parafrazy lub wręcz identyczne przykłady mogą pojawić się w wielu miejscach, zwłaszcza gdy dane generuje się iteracyjnie, w wielu przebiegach i przy użyciu podobnych promptów. Bez twardej separacji train/dev/test wyniki ewaluacji łatwo stają się zawyżone, bo model „rozpoznaje” zadania zamiast demonstrować uogólnienie.
Train służy do uczenia i dostrajania modelu. Dev (walidacyjny) jest do doboru hiperparametrów, selekcji wariantów promptów i decyzji produktowych. Test powinien być możliwie „zamrożony” i używany oszczędnie, wyłącznie do końcowego, porównywalnego pomiaru. Kluczowa zasada: cokolwiek dotyka procesu decyzji (ręcznej lub automatycznej) przestaje być „testem” i staje się elementem dev.
Zasady podziału, które ograniczają przeciek
- Podział po źródłach i „rodzinach”: grupuj przykłady według wspólnego pochodzenia (ten sam prompt bazowy, ta sama persona/scenariusz, ta sama lista faktów wejściowych, ten sam seed lub „pakiet” generacji) i rozdzielaj całe grupy między zbiory. To redukuje sytuacje, w których parafrazy jednego zadania lądują w train i test.
- Podział czasowy lub wersyjny: gdy dane syntetyczne powstają falami, przypisz wcześniejsze partie do train/dev, a nowsze do test (albo odwrotnie, zależnie od celu). Ważne, by test nie był „współtworzony” podczas iteracji nad modelem.
- Podział po trudności i typach zadań: jeśli test ma mierzyć generalizację, nie powinien być jedynie losową próbką z tego samego generatora. Zachowaj reprezentatywność, ale unikaj identycznych schematów. Równocześnie nie „dokręcaj” testu pod konkretne poprawki w modelu.
- Stałe kryteria, brak ręcznego podbierania: selekcja przykładów do testu powinna być deterministyczna i oparta o z góry ustalone reguły, a nie o to, które przykłady „wychodzą ciekawiej”. Ręczne kuratorstwo jest dopuszczalne, ale wtedy należy traktować taki zbiór jako dev, dopóki nie zostanie zamrożony.
- Dedykowany „holdout” dla generatora: jeśli używasz LLM jako generatora danych, odseparuj prompty, szablony i zasoby użyte do budowy testu od tych, które kształtują train. W przeciwnym razie model uczony na danych z jednego stylu generatora będzie testowany na niemal tym samym stylu.
Co dokładnie może „przeciekać”
- Duplikaty dosłowne (identyczne treści, te same wejścia i odpowiedzi).
- Duplikaty semantyczne (parafrazy, przestawione zdania, równoważne liczby i jednostki, zmienione nazwy zmiennych przy zachowaniu struktury).
- Wspólne artefakty generacji (powtarzalne zwroty, te same założenia, podobne „ścieżki rozumowania”); nawet bez duplikatów potrafią sztucznie podbić wyniki.
- Leakage przez metadane: etykiety, identyfikatory lub pola pomocnicze zdradzające odpowiedź, które przypadkiem trafiają do wejścia modelu.
Wersjonowanie zbiorów i „zamrażanie” testu
Bez wersjonowania nie da się uczciwie porównywać modeli ani odtworzyć eksperymentów. Praktyka, która ogranicza chaos: każda partia danych ma jednoznaczny identyfikator wersji, a zbiory train/dev/test są definiowane jako konkretne, niezmienne zrzuty. Zmiana czegokolwiek w definicji podziału (reguł selekcji, filtrów, deduplikacji, normalizacji) oznacza nową wersję. Test powinien mieć status „read-only”: jeśli wykryjesz w nim błąd, poprawka powinna skutkować nową wersją testu, a nie „cichą” edycją.
Śledzenie pochodzenia (provenance) i audytowalność
Dane syntetyczne są szczególnie wrażliwe na utratę kontekstu: po kilku iteracjach trudno ustalić, skąd wziął się przykład i czy nie jest pochodną czegoś, co wylądowało w train. Dlatego każdy rekord powinien mieć komplet metadanych pozwalających na audyt: źródło (syntetyczne/prawdziwe), generator i jego konfigurację, szablon/prompt (lub jego identyfikator), czas i przebieg generacji, przynależność do grupy (rodzina), wszystkie zastosowane filtry i transformacje oraz informację, do którego splitu został przypisany i dlaczego. Dzięki temu można szybko wykryć, czy przykłady z testu nie zostały użyte do trenowania pośrednio (np. przez pomyłkę w pipeline) albo czy nowa partia danych nie jest w istocie wariantem starej.
Minimalny zestaw zasad operacyjnych
- Jedna „prawda” o splitach: jedno miejsce, w którym formalnie zdefiniowany jest podział (reguły + lista identyfikatorów), a pipeline treningowy i ewaluacyjny korzystają z tego samego źródła.
- Nie nadpisuj: aktualizacje danych realizuj przez dopisanie nowej wersji, nie przez modyfikację w miejscu.
- Oddziel uprawnienia: ogranicz dostęp zapisu do testu i loguj każdą zmianę w zbiorach.
- Reprodukowalność: możliwość odtworzenia splitu z metadanych i wersji reguł jest ważniejsza niż „idealny” jednorazowy podział.
Dobrze zaprojektowana separacja train/dev/test wraz z wersjonowaniem i śledzeniem pochodzenia to fundament wiarygodnej oceny. Bez tego syntetyczne dane łatwo prowadzą do pozornych postępów, a model uczy się przede wszystkim rozpoznawać własne ślady zamiast realnie poprawiać generalizację.
8. Przykładowy pipeline end-to-end oraz checklista ryzyk
Dane syntetyczne potrafią szybko „nabić” wolumen i pokryć rzadkie przypadki, ale bez dyscypliny procesowej łatwo wpaść w efekt self-licking ice cream: model uczy się na treściach podobnych do tego, co sam (lub jego „kuzyni” modelowi) generuje, a metryki rosną głównie dlatego, że środowisko testowe upodobniło się do środowiska treningowego. Poniżej jest przykładowy, praktyczny pipeline end-to-end, którego celem jest utrzymanie kontroli nad pochodzeniem danych, różnorodnością i separacją — oraz zwięzła checklista ryzyk, które najczęściej psują wiarygodność wyników.
Pipeline end-to-end (od celu do wdrożenia)
- 1) Definicja celu i kontraktu jakości
Na starcie ustal, do czego dane syntetyczne są potrzebne: domknięcie luk w pokryciu scenariuszy, wzmocnienie odporności na ataki promptowe, większa różnorodność językowa, czy budowa zestawu testowego. Zdefiniuj minimalne wymagania jakościowe (np. poprawność merytoryczna, kompletność, format odpowiedzi), bo inaczej „jakość” zostanie zastąpiona przez „łatwość generacji”. - 2) Specyfikacja przestrzeni danych
Zanim cokolwiek wygenerujesz, opisz przestrzeń: typy zadań, domeny, warianty wejść, poziomy trudności, typowe błędy użytkownika, oczekiwane ograniczenia. Ten krok jest kluczowy, by syntetyki nie stały się jednorodnym „szumem o jednym stylu”. - 3) Plan generacji i plan kontroli
Ustal, jakie modele będą generować (jedno vs wiele źródeł), czy generacja będzie wieloprzebiegowa (np. szkic → dopracowanie → krytyka), oraz jakie mechanizmy zapobiegną „samopowielaniu” (np. wymóg cytowania reguł, wymóg kontrprzykładów, miks stylów i formatów). Celem jest, by pipeline produkował dane celowo zróżnicowane, a nie tylko „ładnie brzmiące”. - 4) Generacja z metadanymi i śledzeniem pochodzenia
Każda próbka powinna mieć metadane: źródło (model/wersja), data, parametry generacji, zamierzony scenariusz, poziom trudności, język, styl oraz identyfikator partii. Bez tego nie da się później rozsądnie mieszać danych, diagnozować degradacji ani wykrywać leakage. - 5) Walidacja i filtracja
Wprowadź bramki jakości: od prostych filtrów (format, długość, zakazane wzorce) po kontrolę spójności (czy odpowiedź odpowiada na pytanie, czy etykiety są zgodne z definicją). W tej fazie odrzucasz próbki, które są podejrzane, zduplikowane, halucynacyjne lub „puste merytorycznie”. - 6) Dedup, decontamination i izolacja zbiorów
Usuń duplikaty i bliskie parafrazy oraz wykonaj odkażanie względem istniejących zbiorów (train/dev/test oraz benchmarków). Następnie przypisz próbki do splitów zgodnie z polityką separacji (w tym separacji „rodzin” zadań), żeby nie testować na wariantach tego, co model widział w treningu. - 7) Kuracja i miks z danymi prawdziwymi
Syntetyki rzadko powinny dominować „bez limitu”. Zastosuj kurację: ogranicz udział partii o podobnej sygnaturze, dołóż dane prawdziwe tam, gdzie liczy się autentyczność języka i dystrybucja błędów użytkownika, a syntetyki używaj do pokrycia luk i kontrolowanych stres-testów. - 8) Trening / dostrajanie i monitoring zachowania
Po treningu nie patrz wyłącznie na średnią metrykę. Sprawdź segmenty (domeny, języki, style, poziomy trudności), a także zachowania brzegowe: odporność na instrukcje sprzeczne, stabilność formatowania, tendencje do konfabulacji. Wzrost metryk przy pogorszeniu zachowań w segmentach to typowy sygnał „przetrenowania na syntetykach”. - 9) Ocena offline i testy kontrolne
Utrzymuj zestawy kontrolne: (a) testy oparte o dane realne, (b) testy syntetyczne generowane „obcym” źródłem, (c) testy regresji na krytycznych przypadkach. Jeśli poprawa pojawia się tylko na danych podobnych do generatora, to ostrzeżenie przed self-licking ice cream. - 10) Publikacja artefaktów procesu i iteracja
Zapisuj raporty: ile odrzucono, dlaczego, jakie segmenty dominują, jak zmienił się rozkład stylu/języka, gdzie wykryto potencjalny leakage. Iteruj: popraw specyfikację przestrzeni danych, źródła różnorodności i bramki jakości zamiast „dogenrowywać więcej tego samego”.
Checklista ryzyk (co najczęściej psuje wiarygodność)
- Bias (stronniczość)
- Nadmierna reprezentacja wygodnych tematów, języków, stylów lub typów użytkowników, bo „łatwo się generują”.
- Utrwalenie stereotypów wynikające z tego, że generator domyślnie wybiera popularne skojarzenia.
- Bias formatowania: preferowanie jednego schematu odpowiedzi (np. zawsze listy), co sztucznie poprawia metryki na podobnych testach.
- Bias trudności: przewaga zadań zbyt łatwych lub „szkolnych”, które nie odzwierciedlają realnych interakcji.
- Leakage (przeciek informacji między zbiorami)
- Przeciek przez parafrazę: test zawiera warianty tego samego problemu, który był w treningu.
- Przeciek przez generator: ten sam model generuje train i test w podobnym stylu, więc model uczony „rozpoznaje dialekt generatora”, a nie rozwiązuje zadanie.
- Przeciek metadanych: w danych zostają sygnały ułatwiające odpowiedź (np. znaczniki, komentarze, konwencje etykiet) przypadkowo skorelowane z klasą.
- Homogenizacja stylu i „modelese”
- Ujednolicone frazy, rytm wypowiedzi, podobne disclaimery i struktury argumentacji.
- Dominacja jednego tonu (np. przesadnie formalny), przez co model traci naturalność w kontakcie z realnym użytkownikiem.
- Spłaszczenie różnorodności błędów: syntetyki bywają zbyt „czyste” i logiczne w porównaniu do prawdziwych zapytań.
- Overfitting na syntetykach
- Wzrost metryk bez wzrostu użyteczności: poprawa jest widoczna głównie na syntetycznych benchmarkach.
- Spadek generalizacji na dane realne: więcej halucynacji lub gorsze radzenie sobie z niejednoznacznością.
- Nadmierne dopasowanie do „sygnatur” generatora: model uczy się heurystyk typowych dla syntetyków (np. zawsze podaje pewną siebie odpowiedź, nawet gdy powinien odmówić).
- Ryzyka operacyjne (procesowe)
- Brak śledzenia pochodzenia: nie da się odtworzyć, dlaczego dana partia pogorszyła model.
- Brak bramek jakości: „więcej danych” zastępuje „lepsze dane”.
- Dryf danych: kolejne iteracje generacji przesuwają rozkład (tematy, styl, trudność), a porównania modeli stają się nieuczciwe.
Dobrze zaprojektowany pipeline traktuje dane syntetyczne jako kontrolowany instrument, nie jako taśmę do masowej produkcji. Najważniejsza zasada praktyczna: jeśli nie potrafisz jednoznacznie powiedzieć, skąd wzięła się próbka i dlaczego jest w danym splicie, to pipeline prędzej czy później zacznie optymalizować się sam na siebie — i wróci efekt „self-licking ice cream”.
Jeśli chcesz poznać więcej takich przykładów, zapraszamy na szkolenia Cognity, gdzie rozwijamy ten temat w praktyce.