-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
314 lines (268 loc) · 15.4 KB
/
Copy path.env.example
File metadata and controls
314 lines (268 loc) · 15.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# =============================================================================
# Mudrc Labeling Pipeline — environment konfigurace
# Cíl HW: NVIDIA Blackwell B200 (1×–8×) + plný NVFP4 stack
# Zkopíruj jako .env: cp .env.example .env
#
# POŽADAVEK: CUDA 13.0+ runtime + NVIDIA driver ≥ 580 na hostu.
# NVFP4 na Blackwell SM120 vyžaduje 5th-gen Tensor Cores, které jsou plně
# podporované až ve CUDA 13. Image tagy SGLang i vLLM níže obsahují "-cu130"
# = explicitní CUDA 13 build. Starší driver = "no kernel image is available"
# error při startu.
# =============================================================================
# --- Cesty ------------------------------------------------------------------
DATA_DIR=./data
CHECKPOINT_DIR=./checkpoints
MODEL_CACHE_DIR=./models
# HuggingFace token
# Nutný pro restricted/gated modely.
# Token musí mít přístup k modelům, které používáš.
HF_TOKEN=hf_TADY_DOPLN_TOKEN
# =============================================================================
# TEST MODELY
# =============================================================================
# Používají se v docker-compose.test.yml.
# Pokud je model gated/restricted, musí být dostupný přes HF_TOKEN.
TEST_EXTRACTOR_MODEL=Qwen/Qwen3-0.6B
TEST_CRITIC_MODEL=google/gemma-3-1b-it
# =============================================================================
# MODELY + KVANTIZACE — plný NVFP4 stack pro produkci
# =============================================================================
#
# DŮLEŽITÉ: NVFP4 modely od RedHatAI a NVIDIA mají kvantizační info VŽDY
# v `config.json` (typicky `quantization_config: { quant_method:
# "compressed-tensors" }`). SGLang a vLLM si ji AUTO-DETECT zjistí.
#
# NEPŘEPISUJ `EXTRACTOR_QUANTIZATION` / `CRITIC_QUANTIZATION` ručně, jinak
# dostaneš chybu:
# ValueError: Quantization method specified in the model config
# (compressed-tensors) does not match the quantization method specified
# in the `quantization` argument (modelopt_fp4).
#
# Tyto env vary nastavuj POUZE pokud:
# - používáš non-NVFP4 model bez `quantization_config` v config.json
# - explicitně chceš FP8 / GPTQ / AWQ fallback
# =============================================================================
# === EXTRACTOR ===============================================================
EXTRACTOR_MODEL=RedHatAI/Qwen3.5-122B-A10B-NVFP4
# EXTRACTOR_QUANTIZATION= # PRÁZDNÉ → SGLang auto-detect z config.json
# === CRITIC ==================================================================
CRITIC_MODEL=nvidia/Gemma-4-31B-IT-NVFP4
# CRITIC_QUANTIZATION= # PRÁZDNÉ → auto-detect z config.json
# === FALLBACK PRESETY ========================================================
# --- FP8 extractor (config.json nemá quantization_config) ---
# EXTRACTOR_MODEL=Qwen/Qwen3.5-122B-A10B-FP8
# EXTRACTOR_QUANTIZATION=fp8
# --- BF16 critic (žádná kvantizace) ---
# CRITIC_MODEL=google/gemma-4-31B-it
# CRITIC_QUANTIZATION=
# CRITIC_TP_SIZE=2
# === REASONING ===============================================================
EXTRACTOR_REASONING=false
CRITIC_REASONING=true
# REVISOR_REASONING=false # default = EXTRACTOR_REASONING
# =============================================================================
# REVISOR (fáze 2b — projde non-ok kritiky a doplní extractor_revised)
# Defaultně používá tentýž endpoint a model jako EXTRACTOR (Qwen3.5).
# Pokud chceš revizi pouštět na jiném modelu, odkomentuj a přepiš:
# =============================================================================
# REVISOR_BASE_URL=http://other-llm:8000/v1
# REVISOR_MODEL=meta-llama/Llama-3.3-70B-Instruct
# REVISOR_CONCURRENCY=32
# REVISOR_MAX_TOKENS=24576
# =============================================================================
# HW: počet GPU pro pipeline
# =============================================================================
# Default: 1 GPU (single-node bezpečný fallback — `docker compose up`
# nepadne na "device error: unknown device" na 1-GPU stroji).
#
# Pro 2× nebo 4× B200: nastav GPU_COUNT a EXTRACTOR_TP_SIZE odpovídajícím
# způsobem (musí být power-of-2: 1, 2, nebo 4 — TP=3 SGLang nepodporuje).
# Nebo použij ./scripts/run_production.sh / run_smoke_test.sh — ty se
# zeptají interaktivně.
GPU_COUNT=1
EXTRACTOR_TP_SIZE=1
CRITIC_TP_SIZE=1
# --- Paralelizace -----------------------------------------------------------
# CONCURRENCY = počet paralelních HTTP requestů, které labeler pošle na endpoint.
# Mělo by zhruba odpovídat backend `max-running-requests` (BATCH_SIZE).
# Pokud máš slabší HW, sniž obě hodnoty.
#
# TIP: max STABILNÍ souběžnost pro tvůj HW (bez runaway) najde a sem rovnou
# zapíše plně automatický tuner — nahodí SGLang + probe kontejner, změří a
# upraví EXTRACTOR_CONCURRENCY + EXTRACTOR_BATCH_SIZE v .env i .env.example:
# ./scripts/auto_tune_concurrency.sh
EXTRACTOR_CONCURRENCY=32
CRITIC_CONCURRENCY=64
# REVISOR_CONCURRENCY=32 # default = EXTRACTOR_CONCURRENCY
# Backend `max-running-requests` — kolik requestů zpracuje server současně.
# Vyšší = lepší throughput, ale víc VRAM pro KV cache.
EXTRACTOR_BATCH_SIZE=32
CRITIC_BATCH_SIZE=64
# --- Output tokens ---------------------------------------------------------
# Velkorysé defaulty pro labelování dlouhých odstavců s mnoha entitami.
# Critic má reasoning ON → potřebuje extra prostor pro thinking trace + JSON,
# proto má víc než extractor. (Runaway smyčku hlídá CRITIC_SPLIT_REPETITION_PENALTY;
# tenhle strop je pro legitimně dlouhý reasoning, ne pro zacyklení.)
EXTRACTOR_MAX_TOKENS=24576
CRITIC_MAX_TOKENS=49152
# REVISOR_MAX_TOKENS=24576 # default = EXTRACTOR_MAX_TOKENS
# --- Context window (input + output) ---------------------------------------
# 65k = velkorysá rezerva pro odstavec + system prompt + examples + output JSON.
# Sniž jen pokud ti dochází VRAM (KV cache škáluje s context-length × batch).
EXTRACTOR_CONTEXT_LEN=65536
CRITIC_CONTEXT_LEN=65536
# --- Chunkování dlouhých textů ---------------------------------------------
# Texty delší než CHUNK_MAX_CHARS znaků se rozdělí na chunky podle vět;
# ve fázi finalize se chunky jednoho dokumentu spojí zpět do jednoho záznamu.
# 12000 znaků ≈ 3-4 k tokenů — pohodlně se vejde do 65k context.
CHUNK_MAX_CHARS=12000
# --- Timeout + retries -----------------------------------------------------
# Per-request HTTP read timeout. NON-streaming response = server drží
# connection otevřenou až do dokončení generace.
#
# Matematika: 32 paralelních requestů × backend aggregate ~1300 tok/s na
# B200 → ~40 tok/s per-request → 24576 max_tokens = ~10 min worst case.
# 1800s (30 min) dává 3× headroom, zabraňuje ReadTimeout retries.
#
# Sniž jen pokud máš lower CONCURRENCY / MAX_TOKENS, nebo rychlejší HW.
LLM_TIMEOUT_S=1800
LLM_MAX_RETRIES=5
# --- Healthcheck: prostor pro studený start (stažení vah z HF) -------------
# Kolik času dostane LLM server, aby naběhl, VČETNĚ prvního stažení vah z
# HuggingFace. Qwen3.5-122B-NVFP4 (~80 GB) se na první (studený) běh stahuje
# klidně desítky minut — když to nestihne, docker prohlásí kontejner za
# unhealthy a strhne ho (smoke i produkce pak hlásí rc=1 / "nestihlo to
# doběhnout" a zkouší další backend).
#
# Default 3600s (1 h); s retries je celkové okno ~90 min. Na pomalé lince
# zvyš (MUSÍ obsahovat jednotku, např. 7200s nebo 120m). Po prvním stažení
# je model v ./models cache → další starty jsou rychlé a velká hodnota je
# NEzpomaluje (healthy se hlásí hned po prvním úspěšném checku).
LLM_HEALTH_START_PERIOD=3600s
# =============================================================================
# FÁZE 0 — TAXONOMY DISCOVERY
# =============================================================================
# Před extrakcí LLM analyzuje vzorek textů ze VŠECH datasetů v DATA_DIR a
# navrhne jednotnou NER taxonomii (auto mode = default; běží v produkci i ve
# smoke testu). Selže-li (extractor nedostupný, prázdná data, …), spadne se na
# 16 originálních kategorií a běh POKRAČUJE — fáze 0 je best-effort.
#
# Počet ukázek per dataset/doména, které jdou LLM na návrh taxonomie.
# JEDNORÁZOVÁ konstanta — neškáluje se s velikostí datasetu. Vyšší = širší
# pokrytí, ale větší prompt (pozor na context window). Default 10.
TAXONOMY_SAMPLES_PER_DATASET=10
# --- Pilíř A / krok 2: DISJOINTNESS AUDIT ----------------------------------
# Po návrhu taxonomie proběhne automatický audit: na held-out vzorcích měří,
# jak často model neumí rozhodnout mezi dvěma labely (konfuze), a zaměňované
# páry sám ZOSTŘÍ (přepíše popis + rozhodovací pravidlo + counter-examples).
# Plně automatické, univerzální, ŽÁDNÁ hard-coded slova, ŽÁDNÝ člověk.
# Best-effort: selže-li, ponechá se taxonomie z návrhu (běh pokračuje).
TAXONOMY_AUDIT_ENABLED=true
# Kolik kol auditu max (každé kolo = 1 měření + zostření nejhorších párů).
TAXONOMY_AUDIT_MAX_ROUNDS=3
# Cílová konfuze (průměrná nejistota top-1 labelu, 0-1). Pod tímto prahem je
# taxonomie dost disjunktní a audit skončí. Nižší = přísnější.
TAXONOMY_AUDIT_TARGET_SCORE=0.15
# Kolik nejzaměňovanějších párů se zostří v jednom kole.
TAXONOMY_AUDIT_MAX_PAIRS=2
# Min. počet zaměněných spanů, aby se pár řešil (chrání před šumem 1 výskytu).
TAXONOMY_AUDIT_MIN_SUPPORT=2
# Strukturální úpravy (SLUČ dva nerozlišitelné labely) — mění POČET labelů.
# Default OFF: audit napřed jen zostřuje hranice. Zapni, až uvidíš čísla.
TAXONOMY_AUDIT_STRUCTURAL_EDITS=false
# =============================================================================
# FÁZE 3 (FINALIZE) — KORPUSOVÉ HLASOVÁNÍ O KATEGORIÍCH
# =============================================================================
# Finalize jako jediná fáze vidí CELÝ korpus najednou. Hlasování posbírá
# rozdělení kategorií pro každé lemma napříč všemi dokumenty a menšinové
# výskyty přelabeluje na dominantní kategorii (stejná entita jednou PRODUKT,
# jinde PRODUKT_TYP → sjednotí se). Plně data-driven — ŽÁDNÁ hard-coded slova,
# ŽÁDNÁ statická priorita labelů. Nejednoznačné klíče (žádná dominance) se
# NEMĚNÍ (entropy guard) a jdou do category_vote_report.json.
# Stejné statistiky řídí i normalize: řešení konfliktů labelů, bezpečnost
# auto-expandu (funkční slova se poznají podle document frequency, ne podle
# vyjmenovaného seznamu) a tie-break překryvů.
CATEGORY_VOTE_ENABLED=true
# Minimální podíl dominantní kategorie (0-1), aby se menšina přelabelovala.
CATEGORY_VOTE_DOMINANCE=0.8
# Minimální počet výskytů lemmatu v korpusu, aby hlas platil.
CATEGORY_VOTE_MIN_SUPPORT=3
# Auto-expand: výraz obsažený ve víc než tomto podílu dokumentů = statistické
# generikum / funkční slovo → nikdy se neexpanduje (nahrazuje stopword seznam).
AUTO_EXPAND_MAX_DF_RATIO=0.5
# =============================================================================
# FÁZE 3 (FINALIZE) — DETERMINISTICKÁ LEMMATIZACE (STANZA)
# =============================================================================
# Dělba práce: LLM vrací jen entity + relace (porozumění textu); lemma je
# mechanická úloha → počítá ji deterministicky Stanza (stejná filozofie jako
# pozice v positions.py). Stanza se používá VÝHRADNĚ na lemma — žádné POS
# filtry ani jiná morfologie. Konzistentní lemmata zlepšují klíče korpusového
# hlasování, chunk-merge dedup i triples.
# Best-effort: bez nainstalované stanzy (pip install stanza) nebo modelu se
# krok přeskočí a zůstanou LLM lemmata — běh se nikdy nezastaví.
STANZA_LEMMA_ENABLED=true
# Jazyk modelu (Stanza podporuje ~70 jazyků; model se stáhne automaticky
# při prvním použití do ~/stanza_resources).
STANZA_LANG=cs
STANZA_USE_GPU=false
# =============================================================================
# SPLIT NER / RE
# =============================================================================
# Každou fázi (extract / critic / revise) rozdělit na DVĚ samostatná LLM
# volání — jedno na entity (NER), druhé na relace (RE) — místo jednoho volání
# nad celým grafem. RE volání vždy dostane už hotové entity jako kontext.
#
# Výhoda: model se soustředí na jednu úlohu → lepší kvalita a méně malformed
# relací. Cena: 2× LLM volání na fázi → ZHRUBA 2× delší běh extract/critic/
# revise (a 2× tokenů). Default ON; pro původní chování (vše v jednom volání)
# nastav false.
SPLIT_NER_RE=true
# --- Anti-runaway brzdy JEN pro split NER/RE volání -------------------------
# NER volání (jen entity) se pod plnou dávkou občas zacyklí a generuje až do
# max_tokens → useknutý JSON → reject. Combined cesta (SPLIT_NER_RE=false) tím
# netrpí. Dvě cílené brzdy (combined cesta je NEdostává):
# - menší token strop pro NER (entity = malý JSON; 8192 je 3× rezerva pro
# legit výstup a zároveň bounduje runaway na zlomek 24576)
# - mírná repetition penalty (rozbije generační smyčku; 1.05 má minimální
# dopad na kvalitu JSON, 1.0 = vypnuto)
EXTRACTOR_NER_MAX_TOKENS=8192
EXTRACTOR_SPLIT_REPETITION_PENALTY=1.05
# Critic split: stejná rep penalty. Critic jede reasoning=ON (thinking) a na
# SGLangu (bez gemma4 reasoning-parseru) se thinking občas zacyklí a dojede do
# CRITIC_MAX_TOKENS → useknutý JSON → reject. 1.05 smyčku rozbije, 1.0 = vypnuto.
# TVRDŠÍ alternativa: CRITIC_REASONING=false (critic vrací JSON přímo, bez
# thinkingu — žádný runaway, výrazně míň KV cache i času; na SGLangu doporučeno).
CRITIC_SPLIT_REPETITION_PENALTY=1.05
# =============================================================================
# SGLANG WORKAROUNDY (volitelné — defaultně vypnuté)
# =============================================================================
# Vypnutí SGLang piecewise CUDA graphs (experimentální feature) — pomáhá, když
# server během prefillu padá s:
# ValueError: q.shape[0] (X) does not match qo_indptr[-1] (Y).
# Piecewise CUDA Graph is enabled by default as an experimental feature.
# To work around this error, add --disable-piecewise-cuda-graph
#
# Můžeš zapnout:
# - per-container (jen extractor / jen critic) — vyšší priorita
# - globálně (oba modely najednou) — fallback, když per-container není
#
# Hodnoty: 1 / true → flag --disable-piecewise-cuda-graph se přidá. Default
# = nenastaveno (SGLang piecewise CUDA graph běží jak SGLang chce).
# Per-container override (platí pro produkci i smoke test):
# EXTRACTOR_DISABLE_PIECEWISE_CUDA_GRAPH=1
# CRITIC_DISABLE_PIECEWISE_CUDA_GRAPH=1
# Globální fallback — aplikuje se na oba modely, pokud nemají vlastní override:
# DISABLE_PIECEWISE_CUDA_GRAPH=1
# =============================================================================
# DOCKER IMAGES — VŠECHNY MUSÍ BÝT BUILD PROTI CUDA 13+
# =============================================================================
# Pokud změníš tagy, ujisti se, že obě image jsou explicitně postavené proti
# CUDA 13 (typicky tag obsahuje "-cu130" nebo "cuda13"). Jinak NVFP4 inference
# na Blackwell SM120 selže s "no kernel image is available".
SGLANG_IMAGE=lmsysorg/sglang:latest-cu130
VLLM_IMAGE=vllm/vllm-openai:latest
EXTRACTOR_BACKENDS=sglang vllm
CRITIC_BACKENDS=sglang vllm
REVISE_BACKENDS=sglang vllm
# --- Dry-run / test ----------------------------------------------------------
EXTRACT_EXTRA_ARGS=