Portuguese
mamba
mamba-3
ssm
muon
muonclip
qk-clip
adamw
optimizer
nope
hybrid-architecture
activation-checkpointing
3d-vision-language
depth-perception
point-cloud
diffusion
stable-diffusion
mixture-of-experts
kohonen
som-attention
random-forest
deep-neural-network
knowledge-distillation
bidirectional-distillation
engram-memory
multimodal
multi-token-prediction
dpo
rlhf
hh-rlhf
pcgrad
long-context
lra-qvit
engineer-agent
integral-state
cython
jev-classifiers
gumbel-softmax
quantization
riemannian-optimization
stiefel-manifold
cython-kernels
gradient-accumulation
vector-quantization
grayscale-detection
joint-perception
self-regulation
signal-table
abmo
ciar
growing-som
pt-br
KHTST v17 — pacote aprimoramento (6 módulos refatorados, defeitos D1–D14 provados doc 29) + controlador HÍBRIDO RM+PI+bisseção + tabela de 18 sinais (AdamW/Muon/PRS/pesos/ABMO/CIAR/crescimento) com nascimento neutro e TelemetryHub total; suíte v17 56✓; regressão v1–v16 zero; Cython prioritário (VICReg delega ao kernel compilado); sem estados de treino; sem segredos
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- PLANO_KHMAMBAJEPA.md +81 -65
- README.md +29 -20
- RELATORIO_KHTST.md +72 -116
- cache_dados/corpus_v16.jsonl +0 -0
- cache_dados/corpus_v16_novos.jsonl +0 -0
- cache_dados/corpus_v2.jsonl +0 -0
- cache_dados/tokenizador.json +0 -0
- cache_dados/tokenizador_v16.json +0 -0
- cache_dados/tokenizador_v17.json +0 -0
- docs/matematica/29-autorregulacao-hibrida-aprimoramentos.md +556 -0
- docs/matematica/29-moe-empacotada-tce-sonicmoe-replayssm.md +0 -346
- docs/matematica/30-autoajuste-multi-metodo.md +0 -266
- graficos/v17/v17_evidencias.png +0 -3
- patches/jepa.py +4 -35
- scripts/21_teste_v17.py +0 -324
- scripts/22_graficos_v17.py +0 -162
- scripts/22_publicar_v17.py +160 -0
- scripts/23_publicar_v17.py +0 -204
- src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/jepa_validator.cpython-312-x86_64-linux-gnu.so +0 -3
- src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/mc_jepa.cpython-312-x86_64-linux-gnu.so +0 -3
- src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/nucleos.cpython-312-x86_64-linux-gnu.so +0 -3
- src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/rco_gsq.cpython-312-x86_64-linux-gnu.so +0 -3
- src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/jepa_validator.o +0 -3
- src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/mc_jepa.o +0 -3
- src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/nucleos.o +0 -3
- src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/rco_gsq.o +0 -3
- src/khtst/acelerado/jepa_validator.cpp +0 -0
- src/khtst/acelerado/jepa_validator.cpython-312-x86_64-linux-gnu.so +0 -3
- src/khtst/acelerado/jepa_validator.pyx +0 -433
- src/khtst/acelerado/mc_jepa.c +1 -1
- src/khtst/acelerado/mc_jepa.cpython-312-x86_64-linux-gnu.so +2 -2
- src/khtst/acelerado/nucleos.c +0 -0
- src/khtst/acelerado/nucleos.cpython-312-x86_64-linux-gnu.so +2 -2
- src/khtst/acelerado/rco_gsq.c +0 -0
- src/khtst/acelerado/rco_gsq.cpython-312-x86_64-linux-gnu.so +2 -2
- src/khtst/acelerado/run_verification.py +0 -368
- src/khtst/acelerado/setup.py +0 -11
- src/khtst/aprimoramento/__init__.py +40 -0
- src/khtst/aprimoramento/autorregulacao_estendida.py +285 -0
- src/khtst/aprimoramento/config.py +107 -0
- src/khtst/aprimoramento/controlador_hibrido.py +208 -0
- src/khtst/aprimoramento/difusao_gradiente.py +243 -0
- src/khtst/aprimoramento/jepa.py +237 -0
- src/khtst/aprimoramento/lambda_c_unificado.py +147 -0
- src/khtst/aprimoramento/metricas_qe_ct.py +191 -0
- src/khtst/aprimoramento/tradeoff_k.py +262 -0
- src/khtst/mamba3/__pycache__/hybrid.cpython-312.pyc +0 -0
- src/khtst/mamba3/__pycache__/kernel.cpython-312.pyc +0 -0
- src/khtst/mamba3/__pycache__/replay.cpython-312.pyc +0 -0
- src/khtst/mamba3/hybrid.py +5 -23
PLANO_KHMAMBAJEPA.md
CHANGED
|
@@ -33,20 +33,26 @@ de parâmetros no treino E na inferência.
|
|
| 33 |
| GSQ+RCO Stiefel total (alinhamento, NoPE, gates, RF) | ✅ v13/v14 | docs 26/27, δ_ort ≤ 3e-6 |
|
| 34 |
| JEPA latente + mundo/sonho (τ, quantil, VOG) | ✅ v15.1 | doc 28 §8 (v15), 49✓ verificar |
|
| 35 |
| **torchao real int8/int4 auto CPU/GPU** | ✅ v16 | doc 28 §§1–4; Teo 28.1–28.4; 237 camadas, 3.92×, Δperda 0.000 |
|
| 36 |
-
| **MC-JEPA VICReg em Cython** (perda+gradiente analítico) | ✅ v16 | Teo 28.9; FD 4.2e-11; ≡ torch 9.6e-9 |
|
| 37 |
-
| **Guarda anti-colapso Brain-JEPA** | ✅ v16 | Teo 28.10 |
|
| 38 |
-
| **Autorregulação RM treino+inferência** | ✅ v16 | Teos 28.5–28.8 |
|
| 39 |
-
| **Datasets robô LeRobot ×4
|
| 40 |
-
| **
|
| 41 |
-
|
|
| 42 |
-
| **
|
| 43 |
-
| **
|
| 44 |
-
| **
|
| 45 |
-
|
|
| 46 |
-
|
|
| 47 |
-
|
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
- **00–13**: SOM e variantes, atenção mista/KV, W8A8, MoE, microunidades,
|
| 52 |
escala por computo, janela 1M indexada.
|
|
@@ -64,27 +70,19 @@ de parâmetros no treino E na inferência.
|
|
| 64 |
centro, eq. 28.12–28.14; guarda anti-colapso); Robbins–Monro
|
| 65 |
multiplicativo (Σa=∞, Σa²<∞; duas escalas de Borkar; sinais lr/λ/MoE;
|
| 66 |
bisseção de temperatura com erro ≤ 2^-k).
|
| 67 |
-
- **29 (v17)**:
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
RELATIVA (infactibilidade do alvo absoluto — lema); momentum (o sinal
|
| 81 |
-
literal diverge — contraexemplo; o inverso converge com a₀·β/(1−β)<2);
|
| 82 |
-
τ_qk por bisseção (erro ≤ (τmax−τmin)/2^k); PRS η_up/η_down com ponto
|
| 83 |
-
fixo exato E[T∞]; percentil/T_ciclo/piso; PESO_MOE (fronteira ½);
|
| 84 |
-
PESO_SOM (ativação 90%) + lema da não-identificabilidade
|
| 85 |
-
autorreferente; ABMO na borda da barreira; CIAR como canal derivativo
|
| 86 |
-
do lr (inflação de variância E[(s₁s₂)²] = E[s₁²]E[s₂²]); crescimento
|
| 87 |
-
em log-razão.
|
| 88 |
|
| 89 |
## 4. Dados (registry único — config.py + streaming.py)
|
| 90 |
|
|
@@ -113,15 +111,17 @@ de parâmetros no treino E na inferência.
|
|
| 113 |
|
| 114 |
## 5. Roteiro (próximas versões)
|
| 115 |
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
| 125 |
- Image-JEPA (máscaras de blocos no espaço latente do CodificadorImagem);
|
| 126 |
- V-JEPA 2 (tubos espaço-temporais no CodificadorVideo — fonte
|
| 127 |
yaak-ai/L2D + 4DNeX quando em SSD);
|
|
@@ -137,7 +137,12 @@ de parâmetros no treino E na inferência.
|
|
| 137 |
4. **v19 — Cython total dos hot-paths**: conv1d seletiva do Mamba-3 e
|
| 138 |
softmax top-k do roteador em Cython/OpenMP (prioridade Cython do
|
| 139 |
requisito); detecção automática CPU/GPU mantida.
|
| 140 |
-
5. **
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
`detectar_dispositivo()`; Mapear Ascend/MACA quando disponível
|
| 142 |
(contrato torch.cuda compatível).
|
| 143 |
|
|
@@ -155,31 +160,42 @@ de parâmetros no treino E na inferência.
|
|
| 155 |
real antes de qualquer corrida longa.
|
| 156 |
- **Gráficos do card**: novas curvas SOBREPOSTAS às antigas com os
|
| 157 |
melhores valores anotados (script 08/16).
|
| 158 |
-
- **Suítes**: TODAS verdes antes de publicar (v1–v17; hoje
|
| 159 |
- **Memória**: este arquivo + worklog.md + RELATORIO_KHTST.md são
|
| 160 |
atualizados TODA versão; redundâncias removidas.
|
| 161 |
|
| 162 |
## 7. Verificação v17 (resumo executável)
|
| 163 |
|
| 164 |
```
|
| 165 |
-
python3
|
| 166 |
-
python3
|
| 167 |
-
python3 patches/verificar_tudo.py # 49 ✓ / 0 ✗
|
| 168 |
-
python3 scripts/21_teste_v17.py --retreinar_tokenizador # vocab 16384
|
| 169 |
-
python3 scripts/21_teste_v17.py --variante baseline_v16 --passos 120
|
| 170 |
-
python3 scripts/21_teste_v17.py --variante v17_khmambajepa --passos 120
|
| 171 |
-
python3 scripts/21_teste_v17.py --relatorio # A/B pareado real
|
| 172 |
```
|
| 173 |
|
| 174 |
-
- v17
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
- Regressão: v1–v16 TODAS verdes (25/36/
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
| GSQ+RCO Stiefel total (alinhamento, NoPE, gates, RF) | ✅ v13/v14 | docs 26/27, δ_ort ≤ 3e-6 |
|
| 34 |
| JEPA latente + mundo/sonho (τ, quantil, VOG) | ✅ v15.1 | doc 28 §8 (v15), 49✓ verificar |
|
| 35 |
| **torchao real int8/int4 auto CPU/GPU** | ✅ v16 | doc 28 §§1–4; Teo 28.1–28.4; 237 camadas, 3.92×, Δperda 0.000 |
|
| 36 |
+
| **MC-JEPA VICReg em Cython** (perda+gradiente analítico) | ✅ v16 | Teo 28.9; FD 4.2e-11 (sem kink); ≡ torch 9.6e-9; ponte autograd |
|
| 37 |
+
| **Guarda anti-colapso Brain-JEPA** | ✅ v16 | Teo 28.10; colapso real 0.0 |
|
| 38 |
+
| **Autorregulação total (RM) treino+inferência** | ✅ v16 | Teos 28.5–28.8; λ_moe_lb 1.0→1.74 (demo); T por entropia-alvo (H=5.0045) |
|
| 39 |
+
| **Datasets robô LeRobot ×4** | ✅ v16 | fetchman 40 (902 instruções reais), endoard/Astra/mulligan com frames orçados |
|
| 40 |
+
| **Datasets matemática ×5** | ✅ v16 | GSM8K/MATH-500/hendrycks×2/OpenR1/IFM — resposta canônica verificável (240 registros) |
|
| 41 |
+
| Tarefas canônicas 14 (robo, matematica) | ✅ v16 | Teo 22.1 preservada; n_intencoes=15 dinâmico |
|
| 42 |
+
| **Pacote `aprimoramento` (6 módulos da rodada, refatorados)** | ✅ v17 | doc 29 §§2–6; 14 defeitos D1–D14 corrigidos; suíte v17 56✓ |
|
| 43 |
+
| **Controlador HÍBRIDO RM+PI+bisseção (recursão única)** | ✅ v17 | Teos 29.14–29.15; setpoint e∞=0 medido; telescoping do D exato |
|
| 44 |
+
| **Tabela de sinais (18 parâmetros: AdamW/Muon/PRS/pesos/ABMO/CIAR/cresc.)** | ✅ v17 | Teo 29.16; nascimento neutro; adaptadores MuonClipAdamW+PRS; TelemetryHub 100% |
|
| 45 |
+
| **λ_diff vivo (hipergradiente exato + âncora)** | ✅ v17 | Teo 29.2; λ* analítico ≡ numérico (5e-3) |
|
| 46 |
+
| **QE+CT com significância (Student-t/Bonferroni)** | ✅ v17 | Teo 29.5; 0/60 falsos-positivos; CT por coordenada |
|
| 47 |
+
| **Trade-off K com Ĉ estimado + unimodalidade** | ✅ v17 | Teos 29.8/29.9; K* fechado ≡ numérico ≤1%; teste do modelo por inclinação |
|
| 48 |
+
| SonicMoE (IO/tile-aware) | ⏳ planejado §5 | — |
|
| 49 |
+
| ReplaySSM | ⏳ planejado §5 | — |
|
| 50 |
+
| Image-JEPA/V-JEPA 2 (espaço/pixel-block) | ⏳ planejado §5 | MC-JEPA (VICReg Cython) já é o alicerce |
|
| 51 |
+
| Audio-JEPA / Point-JEPA / 3D-JEPA | ⏳ planejado §5 | encoders já existem (audio.py, profundidade.py) |
|
| 52 |
+
| Brain-JEPA (fMRI/EEG) | ⏳ parcial | guarda do passo pronta (Teo 28.10); falta dataset |
|
| 53 |
+
| T-JEPA / LeJEPA / BJEPA | ⏳ planejado §5 | — |
|
| 54 |
+
|
| 55 |
+
## 3. Matemática central (índice dos docs 00–29)
|
| 56 |
|
| 57 |
- **00–13**: SOM e variantes, atenção mista/KV, W8A8, MoE, microunidades,
|
| 58 |
escala por computo, janela 1M indexada.
|
|
|
|
| 70 |
centro, eq. 28.12–28.14; guarda anti-colapso); Robbins–Monro
|
| 71 |
multiplicativo (Σa=∞, Σa²<∞; duas escalas de Borkar; sinais lr/λ/MoE;
|
| 72 |
bisseção de temperatura com erro ≤ 2^-k).
|
| 73 |
+
- **29 (v17)**: controlador HÍBRIDO RM+PI (telescoping do termo D =
|
| 74 |
+
c·(e_T−e_0) — nunca desestabiliza; duas escalas de Borkar; anti-windup
|
| 75 |
+
direcional); bisseção do τ_qk com semântica PÓS-CLIP (Teo 24.7: ℓ =
|
| 76 |
+
min(ℓ_nat, τ) — direção do colchete corrigida); tabela de sinais de
|
| 77 |
+
18 parâmetros (Teo 29.16 — segurança estrutural a–d); hipergradiente
|
| 78 |
+
EXATO de λ afim + âncora (ótimo interior provado, Teo 29.2);
|
| 79 |
+
unimodalidade de J1 (raiz única de G estritamente crescente, Teo
|
| 80 |
+
29.9-i) + forma fechada K* e elasticidade C^{d/2}; hinge de variância
|
| 81 |
+
POR DIMENSÃO ≥ poolado (Jensen + lei da variância total, Teo 29.10);
|
| 82 |
+
colapso não é mínimo local (é MÁXIMO do hinge — Teo 29.13, com
|
| 83 |
+
honestidade sobre o kink do autograd); Hoeffding/Student-t com nível
|
| 84 |
+
α controlado (Teo 29.5); CT por coordenada (Teo 29.4); estimação de
|
| 85 |
+
Ĉ por OLS log-log com teste do modelo e shrinkage (Teo 29.8).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
## 4. Dados (registry único — config.py + streaming.py)
|
| 88 |
|
|
|
|
| 111 |
|
| 112 |
## 5. Roteiro (próximas versões)
|
| 113 |
|
| 114 |
+
> **v17 ENTREGUE** (pacote `aprimoramento` + autorregulação híbrida com
|
| 115 |
+
> tabela de 18 sinais — doc 29; os itens abaixo foram RE-AGENDADOS):
|
| 116 |
+
|
| 117 |
+
1. **v18 — SonicMoE**: roteamento consciente de IO (fusão de tiles,
|
| 118 |
+
layout de pesos para GEMM contígua, top-k com índices pré-computados
|
| 119 |
+
por segmento) — alvo: large-batch MoE com banda de memória como
|
| 120 |
+
gargalo; prova: modelo de custo RO(_transferido) e medição A/B.
|
| 121 |
+
2. **v18 — ReplaySSM**: replay de estados ocultos do SSM para retomada
|
| 122 |
+
de contexto longa (guardar/resgatar estado + resumo indexado na
|
| 123 |
+
janela 1M; prova: erro de retomada vs reprocessamento O(T)).
|
| 124 |
+
3. **v19 — JEPA family**:
|
| 125 |
- Image-JEPA (máscaras de blocos no espaço latente do CodificadorImagem);
|
| 126 |
- V-JEPA 2 (tubos espaço-temporais no CodificadorVideo — fonte
|
| 127 |
yaak-ai/L2D + 4DNeX quando em SSD);
|
|
|
|
| 137 |
4. **v19 — Cython total dos hot-paths**: conv1d seletiva do Mamba-3 e
|
| 138 |
softmax top-k do roteador em Cython/OpenMP (prioridade Cython do
|
| 139 |
requisito); detecção automática CPU/GPU mantida.
|
| 140 |
+
5. **v20 — Integração da tabela v17 no treinador**: ligar
|
| 141 |
+
`AutorreguladorEstendido` (opt-in `treino.autorreg_v17.ativo`) com os
|
| 142 |
+
produtores de sinal reais (var do gradiente, taxa de trust do PRS,
|
| 143 |
+
razão L_moe/L_ce, ativação SOM, logit_max das NoPE) e corrida A/B
|
| 144 |
+
pareada antes de qualquer treino longo.
|
| 145 |
+
6. **Hardware chinês (CPU/GPU automático)**: camada de detecção já em
|
| 146 |
`detectar_dispositivo()`; Mapear Ascend/MACA quando disponível
|
| 147 |
(contrato torch.cuda compatível).
|
| 148 |
|
|
|
|
| 160 |
real antes de qualquer corrida longa.
|
| 161 |
- **Gráficos do card**: novas curvas SOBREPOSTAS às antigas com os
|
| 162 |
melhores valores anotados (script 08/16).
|
| 163 |
+
- **Suítes**: TODAS verdes antes de publicar (v1–v17; hoje 17 suítes).
|
| 164 |
- **Memória**: este arquivo + worklog.md + RELATORIO_KHTST.md são
|
| 165 |
atualizados TODA versão; redundâncias removidas.
|
| 166 |
|
| 167 |
## 7. Verificação v17 (resumo executável)
|
| 168 |
|
| 169 |
```
|
| 170 |
+
python3 tests/test_khtst_v17.py # 56 verificações (todas verdes)
|
| 171 |
+
python3 patches/verificar_tudo.py # 49 OK (auditoria canônica)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
```
|
| 173 |
|
| 174 |
+
- **v17**: 14 defeitos D1–D14 corrigidos com prova (doc 29); suíte v17
|
| 175 |
+
56✓ incluindo: hipergradiente exato, λ* analítico ≡ numérico, nível
|
| 176 |
+
do teste de ganho (0/60 falsos-positivos), KDTree ≡ força bruta
|
| 177 |
+
(100 grades), unimodalidade (20k pontos), K* fechado ≡ numérico,
|
| 178 |
+
Jensen per-dim (1000 espectros), fuga do colapso (σ̄ ×30), setpoint
|
| 179 |
+
e∞ = 0.0000 (θ=0.6000 exato), permanência EXATA nos limites,
|
| 180 |
+
TelemetryHub 35 chaves.
|
| 181 |
+
- Regressão: v1–v16 TODAS verdes (25/36/45/37/33/49/45/✓/22/49/68/29/
|
| 182 |
+
28/40/—/53) + smoke18 13✓ — ZERO regressões; nenhum módulo de
|
| 183 |
+
produção modificado (pacote novo, aditivo).
|
| 184 |
+
- **Achado de auditoria da própria v17**: a 1ª implementação do
|
| 185 |
+
ControladorHibrido fazia DUPLA integração do termo I (i_acum somado
|
| 186 |
+
por passo ALÉM do b·e_t per-step) — a suíte prendeu o defeito
|
| 187 |
+
(setpoint não convergia) e a recursão foi corrigida para EXATAMENTE
|
| 188 |
+
a forma do doc 29 (e∞ = 0 medido). Honestidade de processo.
|
| 189 |
+
|
| 190 |
+
## 8. Verificação v16 (histórico)
|
| 191 |
+
|
| 192 |
+
```
|
| 193 |
+
python3 tests/test_khtst_v16.py # 45 verificações (todas verdes)
|
| 194 |
+
python3 src/khtst/verificar_tudo.py # auditoria canônica
|
| 195 |
+
python3 scripts/19_teste_v16.py --relatorio # A/B pareado real
|
| 196 |
+
```
|
| 197 |
+
|
| 198 |
+
- A/B pareado (120 passos, corpus 903): baseline 1.811× vs v16 1.296×
|
| 199 |
+
com JEPA+VICReg — leitura honesta no doc 28 §9 (razão auxiliar e
|
| 200 |
+
Teo 28.7-ii); torchao com Δperda 0.000; autorreg viva (demo).
|
| 201 |
+
- Regressão: v1–v15 TODAS verdes (25/36/✓/37/32/48/44/21/✓/✓/✓/28/27/40).
|
README.md
CHANGED
|
@@ -58,7 +58,7 @@ metrics:
|
|
| 58 |
- meteor
|
| 59 |
---
|
| 60 |
|
| 61 |
-
# KHTST — modelo multimodal PT-BR (
|
| 62 |
|
| 63 |
KHTST é um modelo multimodal compacto para PT-BR com roteamento por S-SOM,
|
| 64 |
janela PARALELA de contexto (**N_MAX_TOKENS 393.216**), classificadores Jev
|
|
@@ -95,27 +95,36 @@ gradiente**. Provas em `docs/matematica/27`.
|
|
| 95 |
> --teto_horas 9.0 --continuar_ate_horas 8.0 --estados_hf`).
|
| 96 |
|
| 97 |
|
| 98 |
-
## O que há de novo no v17 —
|
| 99 |
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|---|---|---|
|
| 102 |
-
| **
|
| 103 |
-
| **
|
| 104 |
-
| **
|
| 105 |
-
| **
|
| 106 |
-
| **
|
| 107 |
-
| **
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
>
|
| 114 |
-
>
|
| 115 |
-
>
|
| 116 |
-
>
|
| 117 |
-
|
| 118 |
-
|
|
|
|
|
|
|
| 119 |
|
| 120 |
| inovação | onde | prova |
|
| 121 |
|---|---|---|
|
|
|
|
| 58 |
- meteor
|
| 59 |
---
|
| 60 |
|
| 61 |
+
# KHTST — modelo multimodal PT-BR (v16 KHMAMBAJEPA: QUANTIZAÇÃO TORCHAO REAL auto CPU/GPU · MC-JEPA VICReg em CYTHON com gradiente analítico · GUARDA ANTI-COLAPSO Brain-JEPA · AUTORREGULAÇÃO TOTAL treino+inferência (Robbins–Monro) · ROBÔ LeRobot ×4 + MATEMÁTICA verificável ×5 · 14 tarefas)
|
| 62 |
|
| 63 |
KHTST é um modelo multimodal compacto para PT-BR com roteamento por S-SOM,
|
| 64 |
janela PARALELA de contexto (**N_MAX_TOKENS 393.216**), classificadores Jev
|
|
|
|
| 95 |
> --teto_horas 9.0 --continuar_ate_horas 8.0 --estados_hf`).
|
| 96 |
|
| 97 |
|
| 98 |
+
## O que há de novo no v17 — PACOTE DE APRIMORAMENTO + AUTORREGULAÇÃO HÍBRIDA (provas em `docs/matematica/29`, memória em `PLANO_KHMAMBAJEPA.md`)
|
| 99 |
|
| 100 |
+
Auditoria completa (lógica + integração + matemática) dos 6 módulos
|
| 101 |
+
submetidos na rodada — `difusao_gradiente`, `metricas_qe_ct`,
|
| 102 |
+
`lambda_c_unificado`, `tradeoff_k`, `jepa`, `config` — com **14 defeitos
|
| 103 |
+
D1–D14 catalogados, corrigidos e PROVADOS** (doc 29, Teos 29.1–29.16).
|
| 104 |
+
Pacote novo `src/khtst/aprimoramento/` — nenhum módulo de produção foi
|
| 105 |
+
modificado (zero regressões; 17 suítes verdes).
|
| 106 |
+
|
| 107 |
+
| correção/aprimoramento | defeito corrigido | prova |
|
| 108 |
|---|---|---|
|
| 109 |
+
| **λ_diff VIVO na difusão**: a "autoajuste por gradiente" do rascunho era triplo código morto (λ sem grad, controlador nunca chamado, perda sem λ). Agora: L(λ)=λ·L_diff+ρ(λ−λ₀)² com **hipergradiente EXATO** (∂L/∂λ = L_diff+2ρ(λ−λ₀), erro ZERO — L é afim+quadrática) e **âncora** que dá ÓTIMO INTERIOR provado λ*=λ₀−L_diff/2ρ; regret do EG ≤ G√(2T·ln(λmax/λmin)) | D1 | Teo 29.2 |
|
| 110 |
+
| **EMA Polyak** no denoiser (avaliar/amostrar com θ̄ — Jensen: L(θ̄) ≤ média L(θ_t)) | D2 | Teo 29.3 |
|
| 111 |
+
| **QE+CT comparáveis**: CT por COORDENADA (÷B·D — a soma bruta crescia com a dimensão); QE relativo a ‖x‖² (invariante a reescala); campo `normalizar` do config VIVO | D3, D14 | Teo 29.4 |
|
| 112 |
+
| **"ganho real" com NÍVEL α controlado**: Student-t unilateral por delta + Bonferroni (α/2 cada) — P(falso ganho) ≤ α; medido: 0/60 falsos-positivos; Hoeffding finito opcional com raio DECLARADO (o range observado INVALIDA a cota — correção honesta da 1ª versão da prova) | D4 | Teo 29.5 |
|
| 113 |
+
| **te_antigo via cKDTree**: O(N·log G) vs O(N·G); ≡ força bruta bit-a-bit em 100 grades | D5 | Teo 29.6 |
|
| 114 |
+
| **λ_c com sinal SUAVIZADO VIVO**: o rascunho computava a média da janela e JOGAVA FORA (usava ε² instantâneo); agora Δ = ε̄²−alvo (Var reduzida ×W, sem viés) + modo reversão + agenda RM opcional (η_t=η₀/(1+t/τ): Ση=∞, Ση²<∞ ⟹ q.c.) | D6, D7 | Teo 29.7 |
|
| 115 |
+
| **Ĉ de Zador ESTIMADO** por OLS log-log (C=1 fixo era irreal): consistência por LLN, TESTE DO MODELO pela inclinação (p̂≈−2/d; se falha, cai para a grade honestamente), shrinkage ao prior; **UNIMODALIDADE de J1 provada** (G(K) estritamente crescente ⟹ raiz única ⟹ minimize_scalar acha o GLOBAL) + forma fechada K*=[(1−λ)2C·ln d/(λd)]^{d/2} + elasticidade honesta ∂lnK*/∂lnC = d/2; λ_c adaptativo integrado | D8, D9 | Teos 29.8/29.9 |
|
| 116 |
+
| **JEPA anti-colapso POR DIMENSÃO**: a variância POOLADA do rascunho não vê colapso parcial (contraexemplo σ=(2,0): poolado 0, per-dim 0,5); Jensen + lei da variância total ⟹ per-dim ≥ poolado SEMPRE; condicional morto removido; **pooling adaptativo** substitui truncamento (contração ‖Pz‖≤‖z‖/√r vs energia descartada); EMA cosseno BYOL opt-in; colapso não é mínimo local (é MÁXIMO do hinge — com honestidade sobre o kink) | D10–D13 | Teos 29.10–29.13 |
|
| 117 |
+
| **CONTROLADOR HÍBRIDO RM+PI+bisseção** — a recursão única u_{t+1}=Π[u_t+a_t·s_t+b·e_t+c·Δe_t], θ=θ₀e^u: telescoping do D (Σc·Δe = c(e_T−e₀) — nunca desestabiliza), duas escalas de Borkar, anti-windup direcional; **τ_qk por banda [80,120] com semântica PÓS-CLIP** (ℓ=min(ℓ_nat,τ) — direção do colchete corrigida; escala exata por Teo 24.7); setpoint convergiu com e∞=0.0000 (θ=0.6000 exato) — **a 1ª implementação tinha DUPLA integração do I; a suíte prendeu e corrigiu** | lacuna estrutural da v16 | Teos 29.14–29.15 |
|
| 118 |
+
| **TABELA DE SINAIS de 18 parâmetros** (a autorregulação agora cobre o que a v16 não cobria): AdamW β₁/β₂/ε/wd, Muon momentum/escala/τ_qk, PRS η_up/η_down/T_ciclo/decay_piso/percentil, PESO_MOE, PESO_SOM, ABMO margem, CIAR κ, crescimento expand/prune — centros = constantes v16 (nascimento NEUTRO), limites seguros (permanência EXATA provada), sinais adimensionais ±1, TelemetryHub registra 100% (35 chaves), adaptadores para MuonClipAdamW real (β/ε/wd/momentum/escala/τ escritos e passo bem definido) e PRS | lacuna estrutural da v16 | Teo 29.16 |
|
| 119 |
+
|
| 120 |
+
> ✅ **v17**: suíte nova 56 verificações verdes; verificar_tudo 49✓;
|
| 121 |
+
> regressão v1–v16 TODAS verdes (25/36/45/37/33/49/45/✓/22/49/68/29/28/
|
| 122 |
+
> 40/—/53) + smoke18 — ZERO regressões. Cython prioritário: o VICReg
|
| 123 |
+
> completo delega ao kernel compilado (`motor=cython` medido) com
|
| 124 |
+
> fallback honesto. Próximo passo: v18 (SonicMoE + ReplaySSM) e v20
|
| 125 |
+
> (integração da tabela no treinador com produtores de sinal reais).
|
| 126 |
+
|
| 127 |
+
## O que há de novo no v16 — KHMAMBAJEPA (provas em `docs/matematica/28`, memória em `PLANO_KHMAMBAJEPA.md`)
|
| 128 |
|
| 129 |
| inovação | onde | prova |
|
| 130 |
|---|---|---|
|
RELATORIO_KHTST.md
CHANGED
|
@@ -814,120 +814,76 @@ re-executada nesta versão. Checkpoints intermediários da coleta v16
|
|
| 814 |
(`ckpt_v16_*.pt`) APAGADOS após uso. Token: exclusivamente variável de
|
| 815 |
ambiente; grep do padrão `hf_[A-Za-z0-9]{30,}` no stage = 0 ocorrências.
|
| 816 |
|
| 817 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
|
| 819 |
-
## 16.
|
| 820 |
-
|
| 821 |
-
|
| 822 |
-
|
| 823 |
-
|
| 824 |
-
|
| 825 |
-
|
| 826 |
-
|
| 827 |
-
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
de
|
| 839 |
-
|
| 840 |
-
|
| 841 |
-
|
| 842 |
-
|
| 843 |
-
|
| 844 |
-
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
|
| 848 |
-
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
| 860 |
-
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
| 874 |
-
|
| 875 |
-
|
| 876 |
-
|
| 877 |
-
|
| 878 |
-
|
| 879 |
-
audita. I1–I4 VERDES em passos reais do treinador.
|
| 880 |
-
- **ReplaySSM** (`mamba3/replay.py`, Teos 29.13–29.14): varredura por S
|
| 881 |
-
segmentos com REPLAY de estados fronteira (checkpoint
|
| 882 |
-
use_reentrant=False; fronteira com grad_fn — SEM detach). **Saída e
|
| 883 |
-
h_L BIT-EXATOS** vs kernel completo (indução na fronteira); **gradiente
|
| 884 |
-
EXATO** (erro 0.0 medido); ativação O(S·BDN + L_s·BDN); cfg
|
| 885 |
-
`mamba3.replay_segmento` (0 = v12 exato, nascimento neutro).
|
| 886 |
-
|
| 887 |
-
### 16.4 Autoajuste multi-método (requisito §§1–4; doc 30)
|
| 888 |
-
|
| 889 |
-
A recursão híbrida **u[t+1] = u[t] + a_t·s_t + b·e_t + c_i·I_t +
|
| 890 |
-
c_d·Δe_t**, θ = exp(u) ∈ [θmin, θmax], cobre TODOS os parâmetros fixos
|
| 891 |
-
com 15 controladores: AdamW β₁/β₂ (PID na CV² do gradiente), ε (RM pela
|
| 892 |
-
razão ‖Δp‖/‖g‖), wd (PID na norma RELATIVA — o alvo absoluto 1.0 é
|
| 893 |
-
infactível: lema com RMS(W_init) ≈ 0.02), Muon momentum (Teo 30.6: o
|
| 894 |
-
sinal literal do requisito forma realimentação POSITIVA — contraexemplo
|
| 895 |
-
provado; o inverso converge com a₀·β/(1−β) < 2), τ_qk por BISSECÇÃO
|
| 896 |
-
(faixa 80–120; erro ≤ (τmax−τmin)/2^k; ocioso com RCO — Teo 27.2), PRS
|
| 897 |
-
V8 η_up/η_down (ponto fixo EXATO E[T∞] = p·η_up/(p·η_up+(1−p)·η_down)),
|
| 898 |
-
T_ciclo/decay_piso (RM na velocidade), percentil (RM na fração de clip),
|
| 899 |
-
PESO_MOE (RM razão−½ — fronteira CE dominante), PESO_ALINHAMENTO_SOM
|
| 900 |
-
(PID na taxa de ativação 90%); ABMO (margem pela folga da barreira —
|
| 901 |
-
equilíbrio na borda, descida garantida em TODO passo), CIAR (canal
|
| 902 |
-
derivativo do lr — dois multiplicadores independentes inflam a variância
|
| 903 |
-
E[(s₁s₂)²] = E[s₁²]E[s₂²]), crescimento (log-razão expansão/poda).
|
| 904 |
-
Convergência: RM (Σa=∞, Σa²<∞) + PID em escala de tempo mais rápida
|
| 905 |
-
(Borkar); anti-windup (integral satura em 1); truncagem ⟹ pertença
|
| 906 |
-
SEMPRE (θ ∈ limites após 2000 passos com sinais máximos). Lema
|
| 907 |
-
30.12-b: coef_streak/vel_alvo/boost_max/alfa_sig ficam FIXOS
|
| 908 |
-
(não-identificabilidade autorreferente). Telemetria integral
|
| 909 |
-
`multi/*` (15 chaves) + `sonic/*` no Hub.
|
| 910 |
-
|
| 911 |
-
### 16.5 Verificação e treino real (vocab 16384 mantido)
|
| 912 |
-
|
| 913 |
-
- Tokenizador RETREINADO @16384 no corpus real (903 registros) —
|
| 914 |
-
requisito "vocab": 16384 preservado (`cache_dados/tokenizador_v17.json`).
|
| 915 |
-
- Suíte v17: 59 ✓ (Problema 1, Problema 2, validator/token rounding/
|
| 916 |
-
auditoria, ReplaySSM, multi-método, integração no treinador com
|
| 917 |
-
passos reais, nascimentos neutros).
|
| 918 |
-
- Regressão: v2–v16 TODAS verdes (36/✓/37/32/48/44/21/✓/✓/✓/28/27/40/45)
|
| 919 |
-
+ verificar_tudo 49✓/0✗ (patches/jepa.py sincronizado por SHA-256).
|
| 920 |
-
- A/B pareado (30 passos, corpus 903, vocab 16384): baseline_v16
|
| 921 |
-
9.727→9.374 (1.038×) vs **v17 9.729→9.301 (1.046×)**; held-out em
|
| 922 |
-
paridade (9.774/9.769); **torchao+MoE-pack com Δperda 0.0** (3.92×);
|
| 923 |
-
TCE normalizada 0.54 (v16: 24.96) com taxa 0.104 (v16: ≡ 0); réplica
|
| 924 |
-
com outro sorteio trocou a ordem CE (paridade — decisão na corrida 9 h).
|
| 925 |
-
|
| 926 |
-
### 16.6 Honestidade
|
| 927 |
-
|
| 928 |
-
(i) Os experts do MoEEncoderDecoder ficam FP32 (limitação v18); (ii) a
|
| 929 |
-
inclinção do PESO_ALINHAMENTO_SOM assume monotonia da resposta — sem ela
|
| 930 |
-
o Teo 30.1 garante apenas pertença; (iii) as escalas multi em corrida de
|
| 931 |
-
120 passos movem-se (constantes aceleradas) mas a CONVERGÊNCIA é
|
| 932 |
-
assintótica; (iv) o A/B de CE em corrida curta não decide qualidade
|
| 933 |
-
definitiva — protocolo 9h do README.
|
|
|
|
| 814 |
(`ckpt_v16_*.pt`) APAGADOS após uso. Token: exclusivamente variável de
|
| 815 |
ambiente; grep do padrão `hf_[A-Za-z0-9]{30,}` no stage = 0 ocorrências.
|
| 816 |
|
| 817 |
+
## 16. v17 — Pacote de aprimoramento: auditoria dos 6 módulos, 14 defeitos provados (D1–D14) e autorregulação HÍBRIDA (RM+PI+bisseção) com tabela de 18 sinais
|
| 818 |
+
|
| 819 |
+
### 16.1 Escopo e método
|
| 820 |
+
|
| 821 |
+
Rodada de auditoria de lógica, integração e matemática dos 6 módulos
|
| 822 |
+
submetidos (`difusao_gradiente`, `metricas_qe_ct`, `lambda_c_unificado`,
|
| 823 |
+
`tradeoff_k`, `jepa`, `config`). Método: auditoria de 1ª ordem (o que o
|
| 824 |
+
código faz) + de 2ª ordem (o que o docstring PROMETE vs o que o código
|
| 825 |
+
FAZ) + prova de correção de cada defeito + suíte executável
|
| 826 |
+
(`tests/test_khtst_v17.py`, 56 verificações). Tudo em pacote NOVO
|
| 827 |
+
`src/khtst/aprimoramento/` — nenhum módulo de produção foi tocado
|
| 828 |
+
(zero regressões: v1–v16 todas verdes).
|
| 829 |
|
| 830 |
+
### 16.2 Defeitos catalogados e corrigidos (doc 29 §§1–6, Teos 29.1–29.13)
|
| 831 |
+
|
| 832 |
+
| # | defeito | correção | prova |
|
| 833 |
+
|---|---|---|---|
|
| 834 |
+
| D1 | difusão: λ_diff sem grad + controlador nunca chamado + perda sem λ — "autoajuste" triplo código morto | hipergradiente EXATO (L afim em λ ⟹ ∂L/∂λ = L_diff, erro ZERO) + âncora ρ(λ−λ₀)² com ótimo interior λ*=λ₀−L_diff/2ρ | Teo 29.2 |
|
| 835 |
+
| D2 | sem EMA de pesos (amostragem ruidosa) | EMA Polyak opt-in (Jensen: L(θ̄) ≤ média L(θ_t)) | Teo 29.3 |
|
| 836 |
+
| D3 | CT somava ‖Δz‖² sobre (B·D) — incomparável entre configs | CT por COORDENADA (÷B·D); invariância por isometria provada | Teo 29.4 |
|
| 837 |
+
| D4 | ganho por conjunção de limiares fixos — sem nível de teste | Student-t + Bonferroni (P(falso ganho) ≤ α; medido 0/60) | Teo 29.5 |
|
| 838 |
+
| D5 | te_antigo O(N·G) | cKDTree O(N·log G), ≡ força bruta (100 grades) | Teo 29.6 |
|
| 839 |
+
| D6 | média da janela COMPUTADA E JOGADA FORA (delta usava ε² instantâneo) | sinal suavizado vivo (Var ÷W, sem viés) + modo reversão | Teo 29.7-i |
|
| 840 |
+
| D7 | passo η constante — convergência só a O(η) | agenda η_t=η₀/(1+t/τ) — Ση=∞, Ση²<∞ ⟹ q.c. | Teo 29.7-ii |
|
| 841 |
+
| D8 | C=1 fixo no modelo de Zador | Ĉ por OLS log-log + teste do modelo (inclinação) + shrinkage | Teo 29.8 |
|
| 842 |
+
| D9 | λ_c estático (não conversava com o controlador) | resolver_K aceita λ_c adaptativo | integração |
|
| 843 |
+
| D10 | condicional com dois ramos idênticos | stop-gradient único explícito | inspeção |
|
| 844 |
+
| D11 | variância POOLADA sobre (T,D) — colapso parcial invisível | hinge POR DIMENSÃO (Jensen + lei da variância total ⟹ per-dim ≥ poolado sempre) | Teo 29.10 |
|
| 845 |
+
| D12 | truncamento de comprimento (descarta energia) | pooling adaptativo (contração ‖Pz‖ ≤ ‖z‖/√r) | Teo 29.11 |
|
| 846 |
+
| D13 | λ_jepa do config nunca usado; 0.01 hard-coded | L = λ_jepa·MSE + peso_var·hinge — campos vivos | Teos 29.10/29.13 |
|
| 847 |
+
| D14 | QECTConfig.normalizar e DifusaoConfig.eta_lambda mortos | wired (QE relativo; passo do EG) | Teo 29.4/29.2 |
|
| 848 |
+
|
| 849 |
+
Honestidades de processo desta rodada: (a) a primeira versão da prova
|
| 850 |
+
do Teo 29.5 usava o range OBSERVADO no Hoeffding — inválido (o raio
|
| 851 |
+
subestimado quebra a cota); corrigida para Student-t (TCL) com
|
| 852 |
+
Hoeffding opcional sob raio DECLARADO; (b) o Teo 29.13 foi refinado: no
|
| 853 |
+
ponto EXATO de colapso há kink (o autograd pode dar 0) — a verdade é
|
| 854 |
+
que o colapso é MÁXIMO do hinge (não mínimo local), e a produção empurra
|
| 855 |
+
a direção explicitamente; (c) a PRIMEIRA implementação do
|
| 856 |
+
ControladorHibrido fazia DUPLA integração do termo I — a suíte prendeu
|
| 857 |
+
(setpoint não convergia) e a recursão foi corrigida para a forma do doc
|
| 858 |
+
29, com convergência EXATA medida (θ=0.6000, e∞=0.0000).
|
| 859 |
+
|
| 860 |
+
### 16.3 Autorregulação híbrida — a arquitetura (doc 29 §§7–9, Teos 29.14–29.16)
|
| 861 |
+
|
| 862 |
+
Recursão única para todo parâmetro regulável:
|
| 863 |
+
`u_{t+1} = Π[u_t + a_t·s_t + b·e_t + c·Δe_t]`, θ=θ₀·e^u, a_t=a₀/(1+t/τ).
|
| 864 |
+
Provas: telescoping do D (Σc·Δe = c·(e_T−e₀) — limitada por 2c·sup|e|
|
| 865 |
+
para TODO T); permanência no conjunto seguro por projeção (com clamp
|
| 866 |
+
final — exp(log b) arredonda a b+ε); duas escalas de Borkar (PI rápido
|
| 867 |
+
rastreia, RM lento converge); anti-windup direcional. τ_qk: banda
|
| 868 |
+
[80,120] com semântica PÓS-CLIP (ℓ=min(ℓ_nat,τ)) — modo escala exata
|
| 869 |
+
(Teo 24.7: linearidade do logit) e modo bisseção com erro ≤
|
| 870 |
+
(τmax−τmin)/2^k. Tabela de 18 parâmetros (AdamW β₁/β₂/ε/wd · Muon
|
| 871 |
+
momentum/escala/τ_qk · PRS η_up/η_down/T_ciclo/decay_piso/percentil ·
|
| 872 |
+
PESO_MOE · PESO_SOM · ABMO · CIAR · crescimento ×2) com nascimento
|
| 873 |
+
neutro (centros = constantes v16), sinais adimensionais ±1, limites
|
| 874 |
+
seguros com permanência EXATA, TelemetryHub 100% (35 chaves) e
|
| 875 |
+
adaptadores aplicados e verificados no MuonClipAdamW REAL e no PRS.
|
| 876 |
+
|
| 877 |
+
### 16.4 Verificação
|
| 878 |
+
|
| 879 |
+
- Suíte v17: 56✓ (hipergradiente, λ* analítico≡numérico, EG converge,
|
| 880 |
+
Polyak, invariâncias QE/CT, nível do teste 0/60, KDTree≡bruta 100/100,
|
| 881 |
+
fast≡ref 10⁴, D6 regressão, Ση/Ση², Ĉ+p̂+shrinkage, unimodalidade 20k,
|
| 882 |
+
K* fechado≡numérico ≤1%, elasticidade d/2, Jensen 1000 espectros,
|
| 883 |
+
contração do pooling, EMA cosseno monótona, máximo do colapso, fuga
|
| 884 |
+
×30, telescoping exato, anti-windup 500 adversos, setpoint e∞=0,
|
| 885 |
+
τ banda, 18 controladores neutros→limites exatos, β₁≤β₂ pelo
|
| 886 |
+
adaptador, hub 35 chaves, passo do otimizador real bem definido,
|
| 887 |
+
PRS 5 campos).
|
| 888 |
+
- verificar_tudo: 49✓ · Regressão v1–v16: TODAS verdes
|
| 889 |
+
(25/36/45/37/33/49/45/✓/22/49/68/29/28/40/—/53) · smoke18: 13✓.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cache_dados/corpus_v16.jsonl
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
cache_dados/corpus_v16_novos.jsonl
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
cache_dados/corpus_v2.jsonl
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
cache_dados/tokenizador.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
cache_dados/tokenizador_v16.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
cache_dados/tokenizador_v17.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
docs/matematica/29-autorregulacao-hibrida-aprimoramentos.md
ADDED
|
@@ -0,0 +1,556 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
# Doc 29 — AUTORREGULAÇÃO HÍBRIDA E APRIMORAMENTOS DO PACOTE (v17)
|
| 3 |
+
#
|
| 4 |
+
# Este documento contém TODAS as provas da rodada v17: a análise lógica,
|
| 5 |
+
# de integração e matemática dos 6 módulos submetidos (difusao_gradiente,
|
| 6 |
+
# metricas_qe_ct, lambda_c_unificado, tradeoff_k, jepa, config), os 14
|
| 7 |
+
# defeitos catalogados (D1–D14), e o PLANO de autorregulação total com a
|
| 8 |
+
# recursão híbrida RM+PI+bisseção e a tabela de sinais para os ~20
|
| 9 |
+
# parâmetros ainda fixos (AdamW, Muon, PRS V8, pesos de perda, ABMO, CIAR,
|
| 10 |
+
# crescimento).
|
| 11 |
+
#
|
| 12 |
+
# Suíte verificadora: tests/test_khtst_v17.py (Todas as verificações
|
| 13 |
+
# numéricas citadas como [V29.x] são executadas nela).
|
| 14 |
+
|
| 15 |
+
# =====================================================================
|
| 16 |
+
# §0 — NOTAÇÃO E FONTES
|
| 17 |
+
# =====================================================================
|
| 18 |
+
# Herda a notação do doc 00. Adiciona-se:
|
| 19 |
+
# θ_t — parâmetro regulável no passo t (escala absoluta);
|
| 20 |
+
# u_t — log-coordenada: θ_t = θ₀·exp(u_t) (multiplicativa);
|
| 21 |
+
# a_t — passo RM: a_t = a₀/(1+t/τ_a);
|
| 22 |
+
# s_t — sinal de aprendizado ∈ [−1,1];
|
| 23 |
+
# e_t — erro de rastreio normalizado: (alvo − medida)/escala;
|
| 24 |
+
# Π_[l,u] — projeção (clipagem) no intervalo [l,u];
|
| 25 |
+
# σ_j — desvio-padrão da dimensão j da representação;
|
| 26 |
+
# ε²(K) — erro de quantização com codebook de K níveis;
|
| 27 |
+
# ℓ_max — logit máximo observado nas atenções NoPE (doc 24).
|
| 28 |
+
#
|
| 29 |
+
# Os módulos vivem em src/khtst/aprimoramento/ (pacote auto-contido,
|
| 30 |
+
# mesma convenção de import relativo do rascunho submetido).
|
| 31 |
+
|
| 32 |
+
# =====================================================================
|
| 33 |
+
# §1 — DIAGNÓSTICO GLOBAL (lógica e integração)
|
| 34 |
+
# =====================================================================
|
| 35 |
+
# Os 6 módulos formam uma PIPELINE coerente de aprimoramento:
|
| 36 |
+
#
|
| 37 |
+
# métricas QE+CT ──(ε² medido)──> λ_c unificado ──(λ_c)──> trade-off K
|
| 38 |
+
# │ │
|
| 39 |
+
# └──(ganho real?)──> decisão de treino K* (codebook)
|
| 40 |
+
#
|
| 41 |
+
# difusão (sonho) ──(L_diff)──> λ_diff vivo (novo em v17)
|
| 42 |
+
# JEPA ──(colapso?)──> hinge de variância ──> VICReg Cython (doc 28)
|
| 43 |
+
#
|
| 44 |
+
# DEFEITOS CATALOGADOS (auditoria 1ª + 2ª ordem, todos corrigidos):
|
| 45 |
+
# D1 difusao: λ_diff com requires_grad=False, AutoLambdaDiff NUNCA
|
| 46 |
+
# chamado, L nem sequer usava λ — "autoajuste" era triplo código
|
| 47 |
+
# morto (docstring anunciava o que o código não fazia).
|
| 48 |
+
# D2 difusao: sem EMA de pesos (Polyak) — amostragem ruidosa.
|
| 49 |
+
# D3 metricas: CT somava ‖Δz‖² sobre (B·D) — escala dependente da
|
| 50 |
+
# dimensão; experimentos incomparáveis.
|
| 51 |
+
# D4 metricas: ganho por conjunção de limiares fixos — teste de
|
| 52 |
+
# hipótese implícito SEM nível controlado.
|
| 53 |
+
# D5 metricas: te_antigo O(N·G) — força bruta.
|
| 54 |
+
# D6 lambda_c: a média da janela era COMPUTADA E JOGADA FORA — o
|
| 55 |
+
# delta usava ε² instantâneo (o docstring prometia a média).
|
| 56 |
+
# D7 lambda_c: passo η constante — convergência só a O(η).
|
| 57 |
+
# D8 tradeoff: C=1 hard-coded — a constante de Zador depende dos
|
| 58 |
+
# dados; com C=1, K* colapsa à borda inferior em d alto.
|
| 59 |
+
# D9 tradeoff: λ_c estático lido do config (não conversava com o
|
| 60 |
+
# controlador de λ_c — integração quebrada).
|
| 61 |
+
# D10 jepa: condicional morto (dois ramos idênticos no use_sg).
|
| 62 |
+
# D11 jepa: variância AGRUPADA sobre (T,D) — anti-colapso fraco
|
| 63 |
+
# (colapso parcial de dimensões é invisível).
|
| 64 |
+
# D12 jepa: truncamento de comprimento — descarta energia.
|
| 65 |
+
# D13 jepa: λ_jepa do config NUNCA usado; peso 0.01 hard-coded.
|
| 66 |
+
# D14 config: QECTConfig.normalizar e DifusaoConfig.eta_lambda eram
|
| 67 |
+
# campos mortos (existiam, nunca lidos).
|
| 68 |
+
#
|
| 69 |
+
# LACUNA ESTRUTURAL (motiva §§7–9): a autorregulação v16 (Teos 28.5–28.8)
|
| 70 |
+
# cobria lr/λ_aux/MoE com RM puro de sinal único — sem rastreio de
|
| 71 |
+
# setpoint, sem memória de regime e SEM cobertura de AdamW (β₁,β₂,ε,wd),
|
| 72 |
+
# Muon (momentum, escala, τ_qk), PRS V8 (η_up, η_down, T_ciclo,
|
| 73 |
+
# decay_piso, percentil), PESO_MOE, PESO_ALINHAMENTO_SOM, ABMO, CIAR e
|
| 74 |
+
# crescimento. A v17 fecha com a recursão híbrida + tabela de sinais.
|
| 75 |
+
|
| 76 |
+
# =====================================================================
|
| 77 |
+
# §2 — DIFUSÃO COM GRADIENTE (Teos 29.1–29.3)
|
| 78 |
+
# =====================================================================
|
| 79 |
+
|
| 80 |
+
# ---------------------------------------------------------------------
|
| 81 |
+
# TEOREMA 29.1 (corretude do DDPM). Sejam α_t = 1−β_t e ᾱ_t = ∏_{s≤t}α_s
|
| 82 |
+
# com q(x_t|x_{t−1}) = N(√α_t·x_{t−1}, β_t·I). Então:
|
| 83 |
+
# (i) q(x_t|x₀) = N(√ᾱ_t·x₀, (1−ᾱ_t)·I);
|
| 84 |
+
# (ii) o amostrador x_{t−1} = (x_t − (1−α_t)/√(1−ᾱ_t)·ε_θ(x_t,t))/√α_t
|
| 85 |
+
# + √β_t·z implementa a média a posteriori de q(x_{t−1}|x_t,x₀)
|
| 86 |
+
# sob a parametrização x₀ = (x_t − √(1−ᾱ_t)·ε)/��ᾱ_t.
|
| 87 |
+
# PROVA. (i) Indução. Base t=1 trivial: x₁ = √α₁x₀ + √(1−α₁)ε, e
|
| 88 |
+
# ᾱ₁ = α₁. Passo: assuma q(x_t|x₀) = N(√ᾱ_t x₀, (1−ᾱ_t)I) e
|
| 89 |
+
# x_{t+1} = √α_{t+1}x_t + √(1−α_{t+1})ε' com ε' ⊥ x_t. Soma de
|
| 90 |
+
# gaussianas independentes:
|
| 91 |
+
# E[x_{t+1}|x₀] = √α_{t+1}·√ᾱ_t·x₀ = √(α_{t+1}ᾱ_t)·x₀ = √ᾱ_{t+1}·x₀,
|
| 92 |
+
# Var = α_{t+1}(1−ᾱ_t) + (1−α_{t+1}) = 1 − α_{t+1}ᾱ_t = 1 − ᾱ_{t+1}.
|
| 93 |
+
# (ii) A posteriori gaussiana (conjugada) dá
|
| 94 |
+
# μ̃_t = [√ᾱ_{t−1}β_t·x₀ + √α_t(1−ᾱ_{t−1})·x_t]/(1−ᾱ_t), σ²=β_t.
|
| 95 |
+
# Substituindo x₀ pela estimativa ε-parametrizada e simplificando
|
| 96 |
+
# (álgebra direta — expandir √ᾱ_t = √α_t·√ᾱ_{t−1}):
|
| 97 |
+
# μ̃_t = [x_t − (1−α_t)/√(1−ᾱ_t)·ε]/√α_t,
|
| 98 |
+
# exatamente a atualização implementada em DifusaoDDPM.sample. ∎
|
| 99 |
+
# Consequência: L_diff = E‖ε − ε_θ(x_t,t)‖² é o objetivo simplificado
|
| 100 |
+
# de Ho et al. (2020), majorante ponderado do VLB — a base do módulo
|
| 101 |
+
# estava correta; os defeitos eram de INTEGRAÇÃO (D1/D2).
|
| 102 |
+
|
| 103 |
+
# ---------------------------------------------------------------------
|
| 104 |
+
# TEOREMA 29.2 (λ_diff vivo — hipergradiente exato, regret do EG, ótimo
|
| 105 |
+
# interior ancorado). Com L(λ) = λ·a + ρ(λ−λ₀)², a = L_diff independente
|
| 106 |
+
# de λ (a rede não depende de λ):
|
| 107 |
+
# (i) ∂L/∂λ = a + 2ρ(λ−λ₀) — EXATO, erro de estimação ZERO (a forma
|
| 108 |
+
# é afim + quadrática; nenhuma diferença finita é necessária).
|
| 109 |
+
# (ii) A descida multiplicativa λ_{t+1} = λ_t·exp(−η·g_t) é descida
|
| 110 |
+
# de gradiente por mirror descent com potencial de entropia
|
| 111 |
+
# h(u)=e^u; para L convexa com |g| ≤ G e λ ∈ [λmin,λmax],
|
| 112 |
+
# R_T := Σ_t L(λ_t) − min_λ Σ_t L(λ)
|
| 113 |
+
# ≤ η·G²·T/2 + ln(λmax/λmin)/η,
|
| 114 |
+
# e com η* = √(2·ln(λmax/λmin)/(G²·T)): R_T ≤ G·√(2T·ln(λmax/λmin))
|
| 115 |
+
# — perda média a O(1/√T) do ótimo (regret de EG clássico;
|
| 116 |
+
# a clipagem só adiciona projeção, que nunca aumenta o regret —
|
| 117 |
+
# propriedade de não-expansão da projeção em Bregman).
|
| 118 |
+
# (iii) Com ρ > 0, L é ESTRITAMENTE CONVEXA (L'' = 2ρ > 0) com
|
| 119 |
+
# minimizador ÚNICO λ* = λ₀ − a/(2ρ), clipado a [λmin,λmax].
|
| 120 |
+
# SEM a âncora (ρ=0), L é afim e o minimizador está SEMPRE numa
|
| 121 |
+
# borda — o EG empurraria λ para o limite e o deixaria lá: a
|
| 122 |
+
# âncora é o que torna o autoajuste não-trivial e dá ÓTIMO
|
| 123 |
+
# INTERIOR provado.
|
| 124 |
+
# PROVA. (i) Derivada termo a termo; λ não afeta a rede. (ii) Análise
|
| 125 |
+
# padrão de mirror descent: telescoping da desigualdade de Fenchel
|
| 126 |
+
# D_h(λ*,λ_{t+1}) ≤ D_h(λ*,λ_t) + η·g_t·(λ_t−λ*) + η²G²/2, soma e
|
| 127 |
+
# rearranjo; o termo de largura é ln(λmax/λmin) pois h(λ*)−h(λ₁) é
|
| 128 |
+
# limitado pela divergência de KL entre Bernoullis proporcionais a
|
| 129 |
+
# λmax/λmin (Cesa-Bianchi & Lugosi 2006, Cap. 2 — rederivado no
|
| 130 |
+
# contexto do pacote). (iii) L'(λ)=0 ⟺ λ* = λ₀−a/(2ρ). ∎
|
| 131 |
+
# [V29.2] Suíte: |L(λ*)−min_numérico| < 1e-9 e hipergradiente exato
|
| 132 |
+
# ≡ autograd (1e-7 relativo).
|
| 133 |
+
|
| 134 |
+
# ---------------------------------------------------------------------
|
| 135 |
+
# TEOREMA 29.3 (Polyak/EMA). Se L é convexa em θ e θ̄ = Σw_tθ_t com
|
| 136 |
+
# w no simplex, então L(θ̄) ≤ Σw_t·L(θ_t) (Jensen). O EMA com peso m
|
| 137 |
+
# tem variância de tracking σ²(1−m)/(1+m) sob ruído i.i.d. de θ —
|
| 138 |
+
# avaliar/amostrar com θ̄ nunca é pior EM MÉDIA que amostrar θ_t.
|
| 139 |
+
# PROVA. Jensen para convexas com pesos do simplex; a variância é a do
|
| 140 |
+
# filtro AR(1): Var[θ̄] = σ²(1−m)²/(1−m²) = σ²(1−m)/(1+m), decrescente
|
| 141 |
+
# em m. ∎ (implementado como ema_atualizar/carregar_ema, opt-in.)
|
| 142 |
+
|
| 143 |
+
# =====================================================================
|
| 144 |
+
# §3 — MÉTRICAS QE + CT (Teos 29.4–29.6)
|
| 145 |
+
# =====================================================================
|
| 146 |
+
|
| 147 |
+
# ---------------------------------------------------------------------
|
| 148 |
+
# TEOREMA 29.4 (comparabilidade dimensional).
|
| 149 |
+
# (i) QE(αx, αx̂) = α²·QE(x,x̂) ⟹ QE_rel = QE/mean‖x‖² é invariante a
|
| 150 |
+
# reescala global (α≠0) — compara camadas/épocas de energias
|
| 151 |
+
# distintas (D14 vivo: cfg.normalizar governa).
|
| 152 |
+
# (ii) CT absoluto é invariante a qualquer reindexação das coordenadas
|
| 153 |
+
# com contagem igual (permutação não muda Σ‖Δz‖²); mas entre
|
| 154 |
+
# configurações com B·D distinto só a média POR COORDENADA
|
| 155 |
+
# CT_norm = Σ_t w_t‖Δz_t‖²/(B·D) estima a MESMA quantidade
|
| 156 |
+
# E[deriva² por coordenada] — estimador não-enviesado.
|
| 157 |
+
# PROVA. (i) Bilinearidade da norma. (ii) Permutação de coordenadas é
|
| 158 |
+
# isometria Euclidiana; para contagens distintas, dividir pelo total
|
| 159 |
+
# torna a soma uma média empírica sobre coordenadas — lei dos grandes
|
| 160 |
+
# números ⟹ convergência à expectativa comum. ∎
|
| 161 |
+
|
| 162 |
+
# ---------------------------------------------------------------------
|
| 163 |
+
# TEOREMA 29.5 (ganho real com nível controlado).
|
| 164 |
+
# (i) Com UCB_m = Δ̄_m + q_{1−α_f}·s_m/√N (Student-t) para m ∈
|
| 165 |
+
# {QE, CT} e α_f = α/2: se NÃO há ganho verdadeiro em nenhum
|
| 166 |
+
# dos dois (Δ̄_m ≥ 0), então P(declarar ganho) ≤ α (Bonferroni:
|
| 167 |
+
# P(∪E_m) ≤ ΣP(E_m) ≤ 2·α_f).
|
| 168 |
+
# (ii) Sob Hoeffding com raio DECLARADO R ≥ range verdadeiro:
|
| 169 |
+
# detectar efeito t exige N ≥ R²·ln(1/α_f)/(2t²).
|
| 170 |
+
# (iii) O raio OBSERVADO não substitui R: R_obs ≤ range verdadeiro
|
| 171 |
+
# com prob. 1, e a cota de Hoeffding com raio subestimado NÃO é
|
| 172 |
+
# válida — usar Student-t (TCL) ou declarar R explicitamente.
|
| 173 |
+
# (Esta (iii) é uma CORREÇÃO da minha própria primeira versão
|
| 174 |
+
# desta prova — honestidade de processo registrada.)
|
| 175 |
+
# PROVA. (i) Para cada m, sob Δ̄_m ≥ 0: P(UCB_m < 0) ≤ P(Δ̄_N − Δ̄_m <
|
| 176 |
+
# −q·s/√N) ≤ α_f pela cobertura unilateral do t de Student (exata
|
| 177 |
+
# sob normalidade, assintótica pelo TCL em geral). União por
|
| 178 |
+
# Bonferroni. (ii) Inverter exp(−2Nt²/R²) ≥ 1−α. (iii) A dedução da
|
| 179 |
+
# cota exige (b−a) do SUPORTE; R_obs é menor com prob. 1. ∎
|
| 180 |
+
|
| 181 |
+
# ---------------------------------------------------------------------
|
| 182 |
+
# TEOREMA 29.6 (KDTree). cKDTree devolve o vizinho mais próximo EXATO:
|
| 183 |
+
# (i) construção O(G·log G), consulta O(log G) média — total
|
| 184 |
+
# O((G+N)·log G) contra O(N·G) da força bruta;
|
| 185 |
+
# (ii) com mínimo único, o índice devolvido ≡ argmin exaustivo
|
| 186 |
+
# (mesma distância, bit-a-bit); empates exatos têm medida zero
|
| 187 |
+
# sob grades contínuas e o tie-break é documentado.
|
| 188 |
+
# PROVA. (i) Propriedade estrutural da árvore k-d balanceada. (ii) Se o
|
| 189 |
+
# mínimo é único, ambos os métodos identificam o MESMO ponto — a
|
| 190 |
+
# função distância ao mais próximo é bem definida. ∎ [V29.6]
|
| 191 |
+
|
| 192 |
+
# =====================================================================
|
| 193 |
+
# §4 — λ_c UNIFICADO (Teo 29.7)
|
| 194 |
+
# =====================================================================
|
| 195 |
+
|
| 196 |
+
# ---------------------------------------------------------------------
|
| 197 |
+
# TEOREMA 29.7 (sinal suavizado e agenda RM).
|
| 198 |
+
# (i) Para amostras i.i.d. com variância σ², a média da janela W
|
| 199 |
+
# tem Var = σ²/W ⟹ o sinal Δ(t) = ε̄²(t) − ε²_alvo tem
|
| 200 |
+
# variância W vezes menor que o ε² instantâneo do rascunho,
|
| 201 |
+
# SEM viés (média não-enviesada). Chebyshev:
|
| 202 |
+
# P(|ε̄²−μ| ≥ t) ≤ σ²/(W·t²).
|
| 203 |
+
# (ii) Com η_t = η₀/(1+t/τ): Ση_t = ∞ (harmônica com log T) e
|
| 204 |
+
# Ση_t² < ∞ (série de Dirichlet) ⟹ condições de Robbins–Monro
|
| 205 |
+
# (1951); com campo de deriva b(u) = −η₀·Δ(ε̄²) Lipschitz no
|
| 206 |
+
# compacto [ln λmin, ln λmax] (λ clipada ⟹ sinal limitado) e
|
| 207 |
+
# ruído de segundo momento finito, u_t converge q.c. ao
|
| 208 |
+
# conjunto estacionário de b (Borkar 2008, Thm 2.1 — mesma
|
| 209 |
+
# família do Teo 28.5).
|
| 210 |
+
# (iii) ref_path_step delega a fast_path_step — identidade bit-a-bit
|
| 211 |
+
# POR CONSTRUÇÃO; equivalencia_numerica fixa a propriedade
|
| 212 |
+
# (n=10⁴ passos, max_diff == 0.0). [V29.7]
|
| 213 |
+
# PROVA. (i) Cálculo direto: Var(X̄) = ΣVar/W² = σ²/W. (ii) Séries: Σ
|
| 214 |
+
# 1/(1+t/τ) diverge como τ·ln T; Σ1/(1+t/τ)² ≤ Σ1/t² converge. O
|
| 215 |
+
# sinal é limitado (modo alvo: |Δ| ≤ max(|ε²|)+alvo, com ε² ≤ B por
|
| 216 |
+
# ser média de quadrados limitados) ⟹ ruído com segundo momento
|
| 217 |
+
# finito e passos satisfazendo as condições clássicas ⟹ Teorema de
|
| 218 |
+
# Robbins–Monro. ∎
|
| 219 |
+
|
| 220 |
+
# =====================================================================
|
| 221 |
+
# §5 — TRADE-OFF K (Teos 29.8–29.9)
|
| 222 |
+
# =====================================================================
|
| 223 |
+
|
| 224 |
+
# ---------------------------------------------------------------------
|
| 225 |
+
# TEOREMA 29.8 (estimação da constante de Zador). Modelo:
|
| 226 |
+
# ln ε²(K) = ln C − (2/d)·ln K + r, E[r]=0, Var[r]<∞, r ⊥ K.
|
| 227 |
+
# (i) OLS em log-log: (Ĉ_ols, p̂) → (C, 2/d) q.c. quando n_C→∞
|
| 228 |
+
# (LLN sobre os momentos amostrais + mapeamento contínuo).
|
| 229 |
+
# (ii) TESTE DO MODELO: p̂ é a inclinação estimada; |p̂ + 2/d| >
|
| 230 |
+
# tolerância ⟹ Zador não vale para esses dados ⟹ o resolvedor
|
| 231 |
+
# cai para a grade (honestidade metodológica, telemetria).
|
| 232 |
+
# (iii) SHRINKAGE: Ĉ = (n_C·Ĉ_ols + κ·C₀)/(n_C+κ) tem
|
| 233 |
+
# Viés = κ(C₀−C)/(n_C+κ) e Var = (n_C/(n_C+κ))²·Var(Ĉ_ols) —
|
| 234 |
+
# troca explícita viés↔variância; sensata quando n_C é pequeno
|
| 235 |
+
# (grade típica: 5–8 pontos).
|
| 236 |
+
# PROVA. (i) OLS 1D é razão de médias amostrais; LLN + Slutsky. (ii)
|
| 237 |
+
# p̂ consistente para a inclinação verdadeira; o teste é a rejeição
|
| 238 |
+
# da restrição p = −2/d. (iii) Cálculo direto de viés/variância da
|
| 239 |
+
# média ponderada. ∎ [V29.8: recupera C conhecido em dados sintéticos
|
| 240 |
+
# com inclinação ≈ −2/d]
|
| 241 |
+
|
| 242 |
+
# ---------------------------------------------------------------------
|
| 243 |
+
# TEOREMA 29.9 (unimodalidade, forma fechada, sensibilidade).
|
| 244 |
+
# Com J1(K) = (1−λ)·C·K^{−p} + λ·(log₂K + K·d/n)/log₂d, p = 2/d > 0:
|
| 245 |
+
# (i) J1'(K) = −(1−λ)C·p·K^{−p−1} + λ·(K^{−1}/ln2 + d/n)/log₂d.
|
| 246 |
+
# Multiplicando por K^{p+1} > 0:
|
| 247 |
+
# G(K) = −(1−λ)C·p + λ·(K^p/ln2 + K^{p+1}·d/n)/log₂d.
|
| 248 |
+
# G é ESTRITAMENTE CRESCENTE (K^p e K^{p+1} o são; coeficientes
|
| 249 |
+
# > 0) ⟹ no máximo UMA raiz. Limites: J1'(K) → −∞ quando
|
| 250 |
+
# K→0⁺ (K^{−p−1} domina K^{−1} pois p+1 > 1) e J1'(K) →
|
| 251 |
+
# λ·d/(n·log₂d) ≥ 0 quando K→∞ ⟹ J1 decresce e depois cresce:
|
| 252 |
+
# MÍNIMO GLOBAL ÚNICO — minimize_scalar bounded acha o global.
|
| 253 |
+
# (ii) Regime n→∞ (termo K·d/n desprezível): G(K)=0 dá
|
| 254 |
+
# K* = [ (1−λ)·2·C·ln d / (λ·d) ]^{d/2}
|
| 255 |
+
# (usando ln2·log₂d = ln d). Forma fechada usada como bracket
|
| 256 |
+
# do numérico e sanity check. [V29.9: |K*_num − K*_fechado|/
|
| 257 |
+
# K* < 1% e varredura fina confirma decresce-então-cresce]
|
| 258 |
+
# (iii) SENSIBILIDADE: K* ∝ C^{d/2} ⟹ ∂ln K*/∂ln C = d/2 — para d
|
| 259 |
+
# alto, K* é extremamente sensível a C; por isso Ĉ usa
|
| 260 |
+
# shrinkage (Teo 29.8-iii) e o resolvedor registra C e p̂ na
|
| 261 |
+
# telemetria. Honestidade: com C≈1 e d=512, K*≈0 — o modelo
|
| 262 |
+
# diz "não use codebook" para λ=0.5, o que é CONSISTENTE com
|
| 263 |
+
# a decadência lenta K^{−2/d}; o interesse prático está em
|
| 264 |
+
# d moderado ou C ≫ 1 (dados não normalizados).
|
| 265 |
+
# (iv) SEÇÃO ÁUREA: fator de contração 0,618 por iteração ⟹ erro
|
| 266 |
+
# ≤ (b−a)·0,618^k no bracket [a,b].
|
| 267 |
+
# PROVA. (i) Cálculo direto + análise de limites; singularidade da raiz
|
| 268 |
+
# pela monotonidade estrita de G. (ii) Álgebra: λ·K^p/(ln2·log₂d) =
|
| 269 |
+
# (1−λ)C·p ⟹ K^p = (1−λ)C·p·ln d/λ com ln2·log₂d = ln d. (iii)
|
| 270 |
+
# Log-diferenciar a forma fechada. (iv) Propriedade do golden section
|
| 271 |
+
# search. ∎
|
| 272 |
+
|
| 273 |
+
# =====================================================================
|
| 274 |
+
# §6 — JEPA (Teos 29.10–29.13)
|
| 275 |
+
# =====================================================================
|
| 276 |
+
|
| 277 |
+
# ---------------------------------------------------------------------
|
| 278 |
+
# TEOREMA 29.10 (hinge de variância POR DIMENSÃO ≥ poolado). Sejam
|
| 279 |
+
# σ_j os desvios-padrão por dimensão (j=1..D) e σ_pool o desvio-padrão
|
| 280 |
+
# POOLADO sobre todos os elementos. Então
|
| 281 |
+
# L_perdim = (1/D)·Σ_j relu(γ − σ_j) ≥ relu(γ − σ_pool) = L_pool,
|
| 282 |
+
# com desigualdade ESTRITA quando as dimensões são heterogêneas — em
|
| 283 |
+
# particular, dimensões COLAPSADAS (σ_j ≈ 0) que o hinge poolado não vê.
|
| 284 |
+
# PROVA. Em duas etapas:
|
| 285 |
+
# (a) Decomposição da variância total (lei de condicionamento):
|
| 286 |
+
# σ_pool² = E_j[σ_j²] + Var_j(μ_j) ≥ E_j[σ_j²] ⟹
|
| 287 |
+
# σ_pool ≥ RMS(σ) ≥ σ̄ := E_j[σ_j] (RMS ≥ média).
|
| 288 |
+
# (b) Jensen para relu (convexa): L_perdim = E_j[relu(γ−σ_j)] ≥
|
| 289 |
+
# relu(γ − σ̄). Como relu(γ−x) é NÃO-CRESCENTE em x:
|
| 290 |
+
# relu(γ−σ̄) ≥ relu(γ−σ_pool) = L_pool. Cadeia: perdim ≥ L_pool. ∎
|
| 291 |
+
# CONTRAEXEMPLO (colapso parcial invisível ao poolado): σ = (2, 0), γ=1.
|
| 292 |
+
# L_pool = relu(1 − σ_pool) com σ_pool² = (4+0)/2 + Var(μ); com μ_j=0:
|
| 293 |
+
# σ_pool = √2 ⟹ L_pool = 0. L_perdim = (relu(−1)+relu(1))/2 = 0,5 > 0.
|
| 294 |
+
# A dimensão morta só é PUNIDA pelo per-dimensão. [V29.10]
|
| 295 |
+
# NOTA (rascunho): z.var(dim=(-2,-1)).mean() calculava a variância
|
| 296 |
+
# POOLADA POR AMOSTRA (sobre T·D elementos) e media no lote — ainda
|
| 297 |
+
# mais fraca que L_pool global.
|
| 298 |
+
|
| 299 |
+
# ---------------------------------------------------------------------
|
| 300 |
+
# TEOREMA 29.11 (pooling adaptativo vs truncamento). Seja P o operador
|
| 301 |
+
# de pooling por médias (blocos de raio r) e T_r o truncamento nas L
|
| 302 |
+
# primeiras posições, T = L·r:
|
| 303 |
+
# (i) ‖Pz‖₂ ≤ ‖z‖₂/√r (P é CONTRAÇÃO): por Cauchy–Schwarz,
|
| 304 |
+
# (Σ_{i∈bloco}z_i)² ≤ r·Σ_{i∈bloco}z_i²; somando os blocos
|
| 305 |
+
# disjuntos: ‖Pz‖² ≤ ‖z‖²/r.
|
| 306 |
+
# (ii) O erro de truncamento é a ENERGIA DESCARTADA:
|
| 307 |
+
# ‖z − T_r z‖² = Σ_{i>L} z_i² — estritamente positivo sempre que
|
| 308 |
+
# há massa além de L; o pooling não descarta massa (preserva a
|
| 309 |
+
# média de cada bloco) e seu excesso de erro é de RESOLUÇÃO,
|
| 310 |
+
# dominado pelo de descarte quando a energia é espalhada — o
|
| 311 |
+
# regime típico de representações treinadas (não concentradas
|
| 312 |
+
# nas primeiras posições).
|
| 313 |
+
# PROVA. (i) Cálculo acima. (ii) Definição + comparação de termos; a
|
| 314 |
+
# alegação de domínio é HONESTA (assumption de energia espalhada,
|
| 315 |
+
# verificável por telemetria: fração de energia além de L). ∎ [V29.11]
|
| 316 |
+
|
| 317 |
+
# ---------------------------------------------------------------------
|
| 318 |
+
# TEOREMA 29.12 (agenda cosseno do EMA). m(t) = 1−(1−m₀)·(cos(πt/T)+1)/2:
|
| 319 |
+
# (i) m(0)=m₀, m(T)=1;
|
| 320 |
+
# (ii) monótona crescente: dm/dt = (1−m₀)·π·sin(πt/T)/(2T) ≥ 0 em
|
| 321 |
+
# [0,T];
|
| 322 |
+
# (iii) variância de tracking do alvo EMA sob ruído i.i.d. de θ:
|
| 323 |
+
# σ²_eff = σ²·(1−m)/(1+m) — DECREASE com m: no fim do treino
|
| 324 |
+
# (m→1) o alvo é mais silencioso exatamente quando a
|
| 325 |
+
# representação já converge (BYOL/MoCo v3 — rederivado).
|
| 326 |
+
# PROVA. (i)/(ii) cálculo direto. (iii) filtro AR(1) estacionário. ∎
|
| 327 |
+
# [V29.12: m(0)=m₀, m(T)→1, monótona em grade fina]
|
| 328 |
+
|
| 329 |
+
# ---------------------------------------------------------------------
|
| 330 |
+
# TEOREMA 29.13 (colapso não é mínimo local). Se a representação colapsa
|
| 331 |
+
# (z constante sobre lote-tempo) e peso_var > 0, então o ponto colapsado
|
| 332 |
+
# NÃO é mínimo local de L_total: o MSE entre constantes é plano a 1ª
|
| 333 |
+
# ordem (∂MSE/∂ẑ = 0), enquanto o hinge de variância atinge ali seu
|
| 334 |
+
# VALOR MÁXIMO (σ_j = 0 ⟹ relu(γ−0) = γ) e QUALQUER perturbação aumenta
|
| 335 |
+
# σ_j (σ_j ≥ 0 com mínimo isolado em 0) ⟹ diminui L_var a 1ª ordem ⟹
|
| 336 |
+
# existe vizinhança com L_total estritamente menor ⟹ descida de
|
| 337 |
+
# gradiente ESCAPA do colapso.
|
| 338 |
+
# HONESTIDADE (kink): em σ_j = 0 exato, σ_j não é diferenciável
|
| 339 |
+
# (subdiferencial); o autograd suaviza e pode devolver gradiente 0 no
|
| 340 |
+
# ponto EXATO — a fuga é geométrica (colapso é máximo do hinge), e a
|
| 341 |
+
# produção garante a direção anti-colapso EXPLICITAMENTE via o
|
| 342 |
+
# empurrão yc/σ² do FunilLatente (v15.1) — duplicação honesta do
|
| 343 |
+
# mecanismo provado. O peso peso_var > 0 é NECESSÁRIO: com peso 0 o
|
| 344 |
+
# colapso vira minimizador do alinhamento puro. ∎
|
| 345 |
+
# [V29.13: L_var(colapsado)=γ; perturbação diminui L_total; treino a
|
| 346 |
+
# partir de init colapsado escapa (variância cresce)]
|
| 347 |
+
|
| 348 |
+
# =====================================================================
|
| 349 |
+
# §7 — CONTROLADOR HÍBRIDO RM + PI (Teo 29.14)
|
| 350 |
+
# =====================================================================
|
| 351 |
+
# Recursão ÚNICA para todo parâmetro θ (a arquitetura do plano):
|
| 352 |
+
#
|
| 353 |
+
# u_{t+1} = Π_[u_min,u_max]( u_t + a_t·s_t + b·e_t + c·Δe_t ),
|
| 354 |
+
# θ_t = θ₀·exp(u_t), a_t = a₀/(1+t/τ_a).
|
| 355 |
+
#
|
| 356 |
+
# TEOREMA 29.14 (estabilidade estrutural do híbrido).
|
| 357 |
+
# (i) TELESCOPING do D-termo: Σ_{t≤T} c·Δe_t = c·(e_T − e_0) —
|
| 358 |
+
# contribuição cumulativa limitada por 2c·sup|e| PARA TODO T.
|
| 359 |
+
# O termo derivativo NUNCA desestabiliza a recursão (contrário
|
| 360 |
+
# do temor clássico com ganhos derivativos em controle).
|
| 361 |
+
# (ii) PERMANÊNCIA NO CONJUNTO SEGURO: por indução, u_t ∈
|
| 362 |
+
# [u_min,u_max] ∀t — a base vale no nascimento (u₀=0, centro
|
| 363 |
+
# dentro dos limites por assert) e a projeção Π fecha o passo
|
| 364 |
+
# indutivo. Com o clamp do I (|i_acum| ≤ 2|b_i|), do sinal
|
| 365 |
+
# (|s_t| ≤ 1) e do passo (|Δu| ≤ passo_max), |u_{t+1}−u_t| ≤
|
| 366 |
+
# passo_max — movimento por passo limitado (anti-windup
|
| 367 |
+
# estrutural: NÃO há explosão do integral).
|
| 368 |
+
# (iii) DUAS ESCALAS (Borkar Ch.6; Teo 28.6 generalizado): com
|
| 369 |
+
# a_t → 0 (escala lenta) e b,c fixos (escala rápida), a
|
| 370 |
+
# dinâmica separa: o laço PI (rápido) rastreia o setpoint —
|
| 371 |
+
# erro de regime e_∞ = 0 para planta estática com ganho finito
|
| 372 |
+
# (ação integral pura) — e o RM (lento) converge q.c. sobre o
|
| 373 |
+
# equilíbrio já estabilizado (o campo lento vê a variável
|
| 374 |
+
# rápida quasi-estacionária).
|
| 375 |
+
# (iv) GANHO RELATIVO: o RM sozinho (v16) converge ao estacionário
|
| 376 |
+
# do CAMPO DE SINAIS, que pode ter viés de regime (ex.: razão
|
| 377 |
+
# L_aux/CE sistematicamente deslocada pela mistura de dados).
|
| 378 |
+
# O PI adiciona rastreio de setpoint EXPLÍCITO: e_t → 0 no
|
| 379 |
+
# equilíbrio, o que RM puro não promete.
|
| 380 |
+
# PROVA. (i) Soma telescópica. (ii) A projeção é não-expansiva e fecha
|
| 381 |
+
# a indução; os clamps limitam o incremento. (iii) Teorema de duas
|
| 382 |
+
# escalas: condição Σa_t = ∞ com a_t→0 e ganhos rápidos O(1);
|
| 383 |
+
# separação de escalas valida a aproximação ODE acoplada. (iv)
|
| 384 |
+
# Definicional (o PI zera erro de regime por construção). ∎ [V29.14:
|
| 385 |
+
# telescoping medido; anti-windup em sinais adversos; rastreio de
|
| 386 |
+
# setpoint com erro → 0]
|
| 387 |
+
|
| 388 |
+
# =====================================================================
|
| 389 |
+
# §8 — τ_qk POR BANDA (Teo 29.15)
|
| 390 |
+
# =====================================================================
|
| 391 |
+
# Objetivo: manter o logit máximo ℓ_max na banda [80,120] ajustando τ.
|
| 392 |
+
# Semântica PÓS-CLIP (Teo 24.7): ℓ_observado = min(ℓ_natural, τ).
|
| 393 |
+
#
|
| 394 |
+
# TEOREMA 29.15 (convergência do controlador de τ).
|
| 395 |
+
# (i) ESCALA EXATA: o logit é LINEAR na escala de W_q
|
| 396 |
+
# (ℓ(γW_q) = γ·ℓ(W_q) — bilinearidade). Logo, com
|
| 397 |
+
# τ_{t+1} = τ_t·(ℓ_alvo/ℓ_t)^η: no caso ℓ_t = min(ℓ_nat, τ_t)
|
| 398 |
+
# com τ_t < ℓ_nat (clip ativo), ℓ_t = τ_t e a iteração em
|
| 399 |
+
# log-escala é log τ_{t+1} = (1−η)·log τ_t + η·log ℓ_alvo —
|
| 400 |
+
# contração geométrica com razão |1−η| (η=1 corrige em 1 passo
|
| 401 |
+
# EXATO; η=0,5 → metade do log-erro por passo).
|
| 402 |
+
# (ii) BISSEÇÃO NO COLCHETE: com a invariância "τ* ∈ [t_lo,t_hi]"
|
| 403 |
+
# (τ* := o τ que põe ℓ_obs na banda), ℓ_obs > hi ⟹ τ ≥ ℓ_obs >
|
| 404 |
+
# hi ⟹ τ* < τ ⟹ t_hi ← τ; ℓ_obs < lo ⟹ τ* > τ ⟹ t_lo ← τ.
|
| 405 |
+
# Com ponto médio geométrico a cada passo, a largura do
|
| 406 |
+
# colchete contrai por 1/2 em log-escala ⟹ erro ≤
|
| 407 |
+
# (τ_max−τ_min)/2^k após k passos (a forma do rascunho,
|
| 408 |
+
# agora com a direção do colchete CORRETA sob pós-clip).
|
| 409 |
+
# PROVA. (i) Substituição direta; a linearidade é o Teo 24.7 (o mesmo
|
| 410 |
+
# invariante do QK-clip). (ii) A atualização do colchete preserva a
|
| 411 |
+
# invariância por construção; largura em log decresce pela metade com
|
| 412 |
+
# midpoint geométrico. ∎ [V29.15: dinâmica consistente
|
| 413 |
+
# ℓ_obs=min(ℓ_nat,τ) converge para a banda; erro do colchete ≤ cota]
|
| 414 |
+
|
| 415 |
+
# =====================================================================
|
| 416 |
+
# §9 — TABELA DE SINAIS: O PLANO DE AUTORREGULAÇÃO TOTAL (Teo 29.16)
|
| 417 |
+
# =====================================================================
|
| 418 |
+
# ARQUITETURA (implementada em autorregulacao_estendida.py):
|
| 419 |
+
#
|
| 420 |
+
# telemetria bruta (TreinadorExtensao) ──> tabela de sinais (±1)
|
| 421 |
+
# ──> ControladorHibrido por parâmetro (RM+PI)
|
| 422 |
+
# ──> valores novos ──> adaptadores (otimizador, PRS, perdas)
|
| 423 |
+
# ──> TelemetryHub (TODOS os valores e erros auditáveis)
|
| 424 |
+
#
|
| 425 |
+
# TEOREMA 29.16 (segurança estrutural da tabela). Para cada linha da
|
| 426 |
+
# tabela:
|
| 427 |
+
# (a) o CENTRO é a constante v16 (nascimento neutro — comportamento
|
| 428 |
+
# bit-a-bit idêntico com autorreg desligada);
|
| 429 |
+
# (b) o centro está DENTRO dos limites (verificação por assert);
|
| 430 |
+
# (c) sinais ∈ [−1,1] (sinal_razao clipa) ⟹ |Δu| ≤ passo_max ⟹
|
| 431 |
+
# permanência no conjunto seguro (Teo 29.14-ii);
|
| 432 |
+
# (d) os CONSUMIDORES aceitam qualquer valor nos limites: AdamW exige
|
| 433 |
+
# β∈(0,1), ε>0, wd≥0 (denominador √exp_avg_sq+ε > 0 — bem
|
| 434 |
+
# definido); Muon exige momentum∈[0,1); PRS exige T_ciclo≥1 e
|
| 435 |
+
# percentil∈[0.5,0.95]; τ_qk∈[40,400] mantém a banda do QK-clip
|
| 436 |
+
# compatível com a cota do logit (Teo 27.2: ℓ_max ≤ d/√d_h).
|
| 437 |
+
# TABELA (18 linhas — parâmetro, controlador, sinal, setpoint, limites):
|
| 438 |
+
# ---------------------------------------------------------------------
|
| 439 |
+
# | parâmetro | ctl | sinal (telemetria) | alvo | limites |
|
| 440 |
+
# | AdamW β₁ | PI | var_grad_norm (curvatura) | 1.0 | [.80,.95] |
|
| 441 |
+
# | AdamW β₂ | PI | deriva_seg_momento (inv.) | 1.0 | [.90,.999]|
|
| 442 |
+
# | AdamW ε | RM | razao_update_grad | 1.0 | [1e-10,1e-6]|
|
| 443 |
+
# | AdamW wd | PI | norma_peso (L2 média) | 1.0 | [1e-4,.10]|
|
| 444 |
+
# | Muon momentum | RM | razao_momentum_grad | 1.0 | [.80,.99] |
|
| 445 |
+
# | Muon escala | PI | razao_rms_mecanismos | 1.0 | [.10,.40] |
|
| 446 |
+
# | τ_qk | BISS| logit_max (banda 80–120) | 100 | [40,400] |
|
| 447 |
+
# | PRS η_up | PI | taxa_acerto_trust | 0.60 | [.01,.15] |
|
| 448 |
+
# | PRS η_down | PI | taxa_acerto_trust (inv.) | 0.60 | [.005,.10]|
|
| 449 |
+
# | PRS T_ciclo | RM | delta_perda_passo | 0.01 | [200,1200]|
|
| 450 |
+
# | PRS decay_piso | RM | delta_perda_passo | 0.01 | [.30,.80] |
|
| 451 |
+
# | PRS percentil | RM | razao_clip | 0.10 | [.50,.95] |
|
| 452 |
+
# | PESO_MOE | RM | razao_moe_ce (inv. direta)| 0.5 | [.005,.08]|
|
| 453 |
+
# | PESO_SOM | PI | ativacao_som | 0.90 | [.01,.20] |
|
| 454 |
+
# | ABMO margem | RM | margem_abmo_norm | 1.0 | [.5,1.5]× |
|
| 455 |
+
# | CIAR κ | PI | taxa_aceitacao_ciar | 0.70 | [.5,2.0]× |
|
| 456 |
+
# | cresc. expand | RM | taxa_expansao | 0.05 | [.5,2.0]× |
|
| 457 |
+
# | cresc. prune | RM | taxa_prune | 0.02 | [.5,2.0]× |
|
| 458 |
+
# ---------------------------------------------------------------------
|
| 459 |
+
# ORIENTAÇÃO DOS SINAIS (justificativa de cada linha):
|
| 460 |
+
# β₁ — variância de gradiente alta (ruído) ⟹ ↑β₁ (memória maior do 1º
|
| 461 |
+
# momento denoise a direção); β₂ — deriva do 2º momento alta ⟹
|
| 462 |
+
# ↓β₂ (adaptar mais rápido); ε — razão ‖update‖/‖g‖ ≠ 1 ⟹ ε
|
| 463 |
+
# restabelece (sinal RM multiplico em log); wd — norma de peso
|
| 464 |
+
# acima do alvo 1.0 ⟹ ↑wd; momentum do Muon — ‖buf‖/‖g‖ vs 1.0;
|
| 465 |
+
# escala — Teo 24.11 (RMS comparável entre mecanismos); τ_qk —
|
| 466 |
+
# banda do logit (Teo 29.15); η_up/η_down — acerto do trust alto
|
| 467 |
+
# ⟹ sobe mais agressivo, baixo ⟹ corta mais; T_ciclo/decay_piso
|
| 468 |
+
# — progresso rápido ⟹ ciclos mais longos (explorar); percentil
|
| 469 |
+
# — clips além do alvo ⟹ admitir mais; PESO_MOE — Teo 28.7-ii
|
| 470 |
+
# (CE é a descida primária; razão L_moe/L_ce ≤ 0.5); PESO_SOM —
|
| 471 |
+
# ativação da memória vs 90%; ABMO — folga da barreira η ≤
|
| 472 |
+
# (2−m)/L̂ (Teo 24.9) escalada conservadoramente; CIAR/cresc —
|
| 473 |
+
# taxas de aceitação/expansão/poda contra alvos declarados.
|
| 474 |
+
# PROVA DE (a)–(d): (a) leitura da tabela; (b) assert no construtor;
|
| 475 |
+
# (c) Teo 29.14-ii; (d) inspeção das condições de denomina-
|
| 476 |
+
# dor/positividade dos consumos — cada limites escolhido para
|
| 477 |
+
# preservá-las. ∎ [V29.16: 18 controladores nascem neutros, movem
|
| 478 |
+
# com sinais sintéticos e permanecem nos limites; hub registra tudo]
|
| 479 |
+
|
| 480 |
+
# =====================================================================
|
| 481 |
+
# §10 — CONFIG (D14) E INTEGRAÇÃO
|
| 482 |
+
# =====================================================================
|
| 483 |
+
# Campos mortos do config do rascunho, agora VIVOS:
|
| 484 |
+
# QECTConfig.normalizar → governa QE relativo (Teo 29.4-i);
|
| 485 |
+
# DifusaoConfig.eta_lambda→ passo do EG de λ_diff (Teo 29.2-ii);
|
| 486 |
+
# Campos NOVOS (cada um com prova correspondente):
|
| 487 |
+
# JEPAConfig.peso_var → Teo 29.10/29.13 (era 0.01 hard-coded);
|
| 488 |
+
# JEPAConfig.ema_cosseno → Teo 29.12 (BYOL, opt-in);
|
| 489 |
+
# DifusaoConfig.rho_ancora→ Teo 29.2-iii (ótimo interior);
|
| 490 |
+
# LambdaCConfig.modo → Teo 29.7-i (alvo vs reversão);
|
| 491 |
+
# LambdaCConfig.eta_agendado/tau_eta → Teo 29.7-ii (RM q.c.);
|
| 492 |
+
# TradeoffKConfig.estimar_C/C_prior/kappa_prior → Teo 29.8;
|
| 493 |
+
# QECTConfig.alpha/n_min → Teo 29.5.
|
| 494 |
+
# INTEGRAÇÃO COM A PRODUÇÃO (sem regressão):
|
| 495 |
+
# • pacote NOVO src/khtst/aprimoramento/ — nenhum módulo existente
|
| 496 |
+
# modificado; verificar_tudo.py (49✓) permanece verde;
|
| 497 |
+
# • JEPA delega o VICReg completo ao kernel Cython existente
|
| 498 |
+
# (khtst.treino.jepa_cython) quando vicreg_lambda>0 — Cython
|
| 499 |
+
# prioritário (requisito do projeto), fallback PyTorch honesto;
|
| 500 |
+
# • a suíte v17 fixa TODAS as propriedades novas (Teos 29.1–29.16).
|
| 501 |
+
|
| 502 |
+
# =====================================================================
|
| 503 |
+
# §11 — VERIFICAÇÃO NUMÉRICA (resumo da suíte v17)
|
| 504 |
+
# =====================================================================
|
| 505 |
+
# [V29.2] hipergradiente exato ≡ autograd (≤1e-7 rel); λ* analítico ≡
|
| 506 |
+
# numérico; EG regret consistente com a cota em simulação.
|
| 507 |
+
# [V29.3] EMA: perda média com θ̄ ≤ perda média com θ (convexidade
|
| 508 |
+
# numérica em quadrática).
|
| 509 |
+
# [V29.4] CT_norm invariante a fatoração (B,D)↔(B',D') com B·D igual;
|
| 510 |
+
# QE_rel invariante a reescala α.
|
| 511 |
+
# [V29.5] nível do teste: sobre N=1000 experimentos nulos, taxa de
|
| 512 |
+
# falso ganho ≤ α+folga; Student-t e Hoeffding (R declarado)
|
| 513 |
+
# concordam no sinal.
|
| 514 |
+
# [V29.6] KDTree ≡ força bruta bit-a-bit em 100 grades aleatórias
|
| 515 |
+
# (mínimos únicos).
|
| 516 |
+
# [V29.7] equivalência fast≡ref (10⁴ passos, 0.0); sinal suavizado
|
| 517 |
+
# responde à média da janela (regressão do D6); agenda RM
|
| 518 |
+
# satisfaz Ση=∞, Ση²<∞ numericamente.
|
| 519 |
+
# [V29.8] Ĉ recupera C sintético (erro ≤ 10% com shrinkage); p̂ ≈ −2/d.
|
| 520 |
+
# [V29.9] unimodalidade em varredura fina (20k pontos); K* fechado ≡
|
| 521 |
+
# numérico (≤1%); sensibilidade C^{d/2} confirmada em dupla
|
| 522 |
+
# precisão.
|
| 523 |
+
# [V29.10] contraexemplo σ=(2,0): per-dim > poolado (0.5 > 0); Jensen
|
| 524 |
+
# vale em 1000 sorteios de espectros.
|
| 525 |
+
# [V29.11] pooling não-expansivo (‖Pz‖ ≤ ‖z‖/√r medido); energia de
|
| 526 |
+
# truncamento ≥ erro de pooling no regime espalhado.
|
| 527 |
+
# [V29.12] m(0)=m₀, m(T)→1, monótona.
|
| 528 |
+
# [V29.13] colapso: var_loss > 0 e gradiente não-nulo no ponto constante.
|
| 529 |
+
# [V29.14] telescoping exato; anti-windup sob sinal adverso constante;
|
| 530 |
+
# rastreio de setpoint e_∞ ≈ 0.
|
| 531 |
+
# [V29.15] τ converge à banda sob ℓ_obs=min(ℓ_nat,τ); erro do colchete
|
| 532 |
+
# ≤ (τmax−τmin)/2^k.
|
| 533 |
+
# [V29.16] 18 controladores nascem neutros (θ=centro), movem com
|
| 534 |
+
# sinais e permanecem nos limites; TelemetryHub registra.
|
| 535 |
+
|
| 536 |
+
# =====================================================================
|
| 537 |
+
# §12 — REGRAS OPERACIONAIS (v17)
|
| 538 |
+
# =====================================================================
|
| 539 |
+
# R1. Nenhum parâmetro regulável novo entra em produção SEM linha na
|
| 540 |
+
# tabela de sinais (centro=constante atual, limites seguros, prova
|
| 541 |
+
# de orientação do sinal).
|
| 542 |
+
# R2. Todo controlador nasce NEUTRO e desligado em produção (opt-in);
|
| 543 |
+
# corridas de demonstração podem acelerar a0/τ_a.
|
| 544 |
+
# R3. Sinais são SEMPRE adimensionais (∈[−1,1]) — sinal_razao é o único
|
| 545 |
+
# ponto de normalização.
|
| 546 |
+
# R4. Nenhum sinal instantâneo cru governa um controlador: médias de
|
| 547 |
+
# janela com teto de RAM (Teo 29.7-i) são obrigatórias.
|
| 548 |
+
# R5. Todo teste de "ganho real" usa nível α controlado (Teo 29.5);
|
| 549 |
+
# limiares fixos são no máximo condição necessária.
|
| 550 |
+
# R6. Modelos paramétricos (Zador) são SEMPRE acompanhados do teste do
|
| 551 |
+
# modelo (inclinação) e de fallback honesto (grade).
|
| 552 |
+
# R7. Anti-colapso é SEMPRE por dimensão (Teo 29.10) — hinge poolado é
|
| 553 |
+
# proibido em código novo.
|
| 554 |
+
# R8. τ_qk só cresce dentro da banda [40,400] e nunca anula a cota
|
| 555 |
+
# estrutural do logit (Teo 27.2).
|
| 556 |
+
|
docs/matematica/29-moe-empacotada-tce-sonicmoe-replayssm.md
DELETED
|
@@ -1,346 +0,0 @@
|
|
| 1 |
-
# 29 — KHMAMBAJEPA v17: MoE EMPACOTADA · TCE CURADA · SONICMOE + REPLAYSSM · TOKEN ROUNDING CTHONIANO
|
| 2 |
-
|
| 3 |
-
*Doc matemático da v17 — a MoE deixa de ser excluída da quantização
|
| 4 |
-
(árvores/florestas/indexadores contra o empilhamento que quebra o contrato
|
| 5 |
-
de subclasses), a perda TCE da suíte v16 é diagnosticada e curada com
|
| 6 |
-
provas, o SonicMoE ganha auditoria de memória em tempo real (I1–I4) e o
|
| 7 |
-
Token Rounding exato vive no kernel Cython `jepa_validator`, e o ReplaySSM
|
| 8 |
-
troca memória por recomputação com gradiente BIT-EXATO.*
|
| 9 |
-
|
| 10 |
-
---
|
| 11 |
-
|
| 12 |
-
## 0. Escopo e honestidade
|
| 13 |
-
|
| 14 |
-
A v17 mantém TUDO o que estava provado (docs 00–28) e resolve os DOIS
|
| 15 |
-
problemas abertos da rodada + os dois subsistemas novos. Cada teorema vem
|
| 16 |
-
com a verificação empírica executada nesta versão (suíte
|
| 17 |
-
`tests/test_khtst_v17.py`, 59 verificações verdes; `run_verification.py`
|
| 18 |
-
8 blocos verdes; treino real pareado em `telemetria_out/metricas_v17/`).
|
| 19 |
-
O que NÃO se afirma: (i) que os experts do `MoEEncoderDecoderKHTST` estão
|
| 20 |
-
quantizados — seu forward é por módulo (sem stack), mas `agrupar()` e a
|
| 21 |
-
telemetria assumem pesos planos; eles ficam FP32 e constam como limitação
|
| 22 |
-
honesta (§2.5); (ii) que a v17 supera o baseline v16 em CE em 120 passos —
|
| 23 |
-
o A/B pareado (§10) reporta o que medir, com a leitura matemática.
|
| 24 |
-
|
| 25 |
-
---
|
| 26 |
-
|
| 27 |
-
## 1. PROBLEMA 1 — o empilhamento quebra o contrato de subclasses
|
| 28 |
-
|
| 29 |
-
### Diagnóstico (bug v16, agora evidência executável)
|
| 30 |
-
|
| 31 |
-
O forward vetorial da `MoEAgrupavel` empilha os pesos dos experts ativos:
|
| 32 |
-
|
| 33 |
-
$$W_{\text{gate}} = \operatorname{stack}\{W^{(e)}_{\text{gate}}\}_{e \in A}.$$
|
| 34 |
-
|
| 35 |
-
Após `quantize_`, `W^{(e)}` é um **subclass** `Int8Tensor` (int8 +
|
| 36 |
-
escala por canal). A sonda `sonda_opset_subclass()` executa e prova:
|
| 37 |
-
|
| 38 |
-
| operação | Int8Tensor | consequência |
|
| 39 |
-
|---|---|---|
|
| 40 |
-
| `aten.stack` | **NotImplementedError** | forward v16 crasha ⟹ exclusão Teo 28.3-iv |
|
| 41 |
-
| `narrow`/slice | OK | **indexador legal** (Teo 29.2) |
|
| 42 |
-
| `F.linear` | OK (int8pack) | GEMM nativa consumindo int8 |
|
| 43 |
-
|
| 44 |
-
### Teorema 29.1 (bijeção φ do empacotamento plano)
|
| 45 |
-
|
| 46 |
-
Sejam $W^{(e)} \in \mathbb{R}^{f\times d}$ os pesos FP32 dos $N$ experts e
|
| 47 |
-
$W_{\text{pool}} = [W^{(0)}; \dots; W^{(N-1)}] \in \mathbb{R}^{Nf\times d}$
|
| 48 |
-
o pool. A aplicação $\varphi(e,i) = e\cdot f + i$ é uma **bijeção** de
|
| 49 |
-
$\{0..N{-}1\}\times\{0..f{-}1\}$ em $\{0..Nf{-}1\}$ e vale
|
| 50 |
-
$W_{\text{pool}}[\varphi(e,i)] = W^{(e)}[i]$ **bit-exato** (cópia de
|
| 51 |
-
memória — `torch.cat`). Como a quantização é POR LINHA, a escala da linha
|
| 52 |
-
$r$ no pool é a MESMA que a do expert dono da linha:
|
| 53 |
-
|
| 54 |
-
$$s_r = \frac{\max_r - \min_r}{2^b - 1},$$
|
| 55 |
-
|
| 56 |
-
logo dequantizar a fatia ≡ dequantizar o expert individual, **bit-exato**
|
| 57 |
-
(nenhuma informação nova, nenhuma perdida). ∎
|
| 58 |
-
*Verificação: `indexador_bit_exato_linha = True` no pack; erro da fatia ≤
|
| 59 |
-
cota $h/\sqrt{12}$ do Teo 28.1.*
|
| 60 |
-
|
| 61 |
-
### Teorema 29.2 (indexador por fatias — substituto do stack)
|
| 62 |
-
|
| 63 |
-
A fatia do expert $e$ é $W^{(e)}_{\text{q}} = W_{\text{pool,q}}.\mathrm{narrow}(0,\, e f,\, f)$
|
| 64 |
-
— visão **zero-copy** dentro do subclass. Como `narrow` ∈ opset do
|
| 65 |
-
Int8Tensor (sonda) e `F.linear` ∈ opset, o forward
|
| 66 |
-
$y_e = F.\mathrm{linear}(x, W^{(e)}_{\text{q}})$ despacha o kernel int8
|
| 67 |
-
nativo SEM materializar empilhamento algum. A igualdade com o forward
|
| 68 |
-
FP32 segue de Teo 28.1/28.2 (erro de quantização por camada ≤ $h/\sqrt{12}$
|
| 69 |
-
por linha; propagação pela condição da camada). ∎
|
| 70 |
-
*Verificação: Δy relativo = 6.6e-03 (suíte v17 §1) ≤ cota.*
|
| 71 |
-
|
| 72 |
-
### Teorema 29.3 (floresta de B blocos — índice de 2 níveis)
|
| 73 |
-
|
| 74 |
-
Particione os experts em $B$ blocos contíguos de $\lceil N/B\rceil$; o
|
| 75 |
-
bloco $b$ é um pool próprio $W^{(b)}_{\text{q}}$. O índice vira
|
| 76 |
-
$e \mapsto (b(e), j(e)) = (\lfloor e/\lceil N/B\rceil\rfloor,\ e \bmod \lceil N/B\rceil)$.
|
| 77 |
-
Propriedades provadas:
|
| 78 |
-
|
| 79 |
-
1. **Exatidão**: as linhas de $W^{(b)}$ são as mesmas de $W_{\text{pool}}$
|
| 80 |
-
(mesma $\varphi$ restrita) ⟹ fatia$(b,j)$ ≡ fatia$_{\text{plana}}(e)$
|
| 81 |
-
bit-exato;
|
| 82 |
-
2. **GEMM por bloco**: com o bloco inteiro ativo, gate/up são UM
|
| 83 |
-
`F.linear` cada sobre linhas contíguas (o reshape da SAÍDA é tensor
|
| 84 |
-
plano — legal); o `down` por fatia por expert (a SwiGLU é
|
| 85 |
-
$d\!\to\!f\!\to\!f\!\to\!d$: as linhas do down de um expert NÃO são
|
| 86 |
-
contíguas na saída do gate — o índice 2 níveis dá a fatia exata;
|
| 87 |
-
$n_b \le \lceil N/B\rceil$ pequenos);
|
| 88 |
-
3. **Custo do índice**: $B$ views armazenadas vs $N$; $B{=}1$ recupera o
|
| 89 |
-
pool plano. ∎
|
| 90 |
-
*Nota v17.1: $f$ é POR PAPEL — gate/up têm $f$ linhas = d_ff_expert,
|
| 91 |
-
down tem $d$ linhas = d_model (bug de forma corrigido e coberto pela
|
| 92 |
-
suíte).*
|
| 93 |
-
|
| 94 |
-
### Teorema 29.4 (rollback sem `copy_` sobre subclass)
|
| 95 |
-
|
| 96 |
-
O rollback atômico restaura os pesos FP32 originais salvos e remove as
|
| 97 |
-
views. `load_state_dict` NÃO serve: `copy_` plain→Int8Tensor falha
|
| 98 |
-
(`'Tensor' object has no attribute 'qdata'` — evidência). A restauração
|
| 99 |
-
v17 substitui `param.data` por tensor plano quando a classe difere (o
|
| 100 |
-
despacho do forward volta ao kernel FP32 padrão) e usa `copy_` só entre
|
| 101 |
-
classes iguais ⟹ estado pós-rollback **bit-idêntico** ao pré-pack (cota
|
| 102 |
-
superior — nunca piora). Os pools NÃO são serializados: são DADOS
|
| 103 |
-
DERIVADOS de $(\theta_{\text{orig}}, \text{modo})$ por função
|
| 104 |
-
determinística ⟹ recriáveis com `empacotar_moe` após carregar
|
| 105 |
-
(não-serialização sem perda de informação). ∎
|
| 106 |
-
*Verificação: rollback bit-exato (suíte v17 §1); `pools` ausente do
|
| 107 |
-
state_dict; A/B real com `torchao_degradacao_perda` medido (§10).*
|
| 108 |
-
|
| 109 |
-
### 2.5 Limitação honesta
|
| 110 |
-
|
| 111 |
-
`MoEEncoderDecoderKHTST` (2 encoders + 4 decoders): forward por módulo
|
| 112 |
-
(sem stack) MAS `agrupar()` (fusão ponderada) e a telemetria de uso
|
| 113 |
-
assumem pesos planos. Os 6 experts permanecem FP32 na inferência
|
| 114 |
-
quantizada — custo: $6 \times 3 \times d \times f \times 4$ bytes. A
|
| 115 |
-
cura completa (pools + desvio no `_executa_experts`) é v18.
|
| 116 |
-
|
| 117 |
-
---
|
| 118 |
-
|
| 119 |
-
## 2. PROBLEMA 2 — a perda TCE da suíte v16: causa e cura
|
| 120 |
-
|
| 121 |
-
### Diagnóstico medido (telemetria v16 real)
|
| 122 |
-
|
| 123 |
-
`telemetria_out/metricas_v16_v16_khmambajepa.json`:
|
| 124 |
-
`jepa/perda = 24.96`, `jepa/taxa_sucesso = 0.0`, `var_latente = 0.68`
|
| 125 |
-
(sem colapso — a perda alta NÃO é colapso; é escala).
|
| 126 |
-
|
| 127 |
-
### Teorema 29.5 (magnitude ∝ d — a soma do Huber)
|
| 128 |
-
|
| 129 |
-
Com latentes esféricos (FunilLatente, $\|f(x)\|_2 = \sqrt{d}$), cada
|
| 130 |
-
componente tem $E[e_j^2] \approx 1$ no arranque. O Huber com $\delta=1$
|
| 131 |
-
por componente tem $E[\mathrm{Huber}(e_j)] = c_H \in (0.3, 0.5)$ para
|
| 132 |
-
componentes ~unitários, logo
|
| 133 |
-
|
| 134 |
-
$$L_{\text{v16}} = \sum_{j=1}^{d} \mathrm{Huber}(e_j) \approx c_H \cdot d
|
| 135 |
-
\quad (d = 64 \Rightarrow L \approx 25 — \textbf{medido } 24.96).$$
|
| 136 |
-
|
| 137 |
-
**Cura (normalização dimensional)**: $L \leftarrow L/d$. Por
|
| 138 |
-
LINEARIDADE da perda em cada componente (o Huber é aplicado
|
| 139 |
-
elemento-a-elemento e a soma é linear),
|
| 140 |
-
|
| 141 |
-
$$\nabla_\theta (L/d) = \tfrac{1}{d}\nabla_\theta L \quad \text{EXATAMENTE},$$
|
| 142 |
-
|
| 143 |
-
logo a regra é uma **reparametrização pura** $\lambda' = \lambda\cdot d$:
|
| 144 |
-
o ponto estacionário é o MESMO e a v16 é recuperada com
|
| 145 |
-
$\lambda' = \lambda_{v16}\cdot d$. Ganhos: (i) a razão $L/\mathrm{CE}$
|
| 146 |
-
fica O(1) — comparável entre arquiteturas e com a fronteira ½ do Teo
|
| 147 |
-
28.7-ii; (ii) a autorregulação RM de λ_jepa torna-se BEM DEFINIDA (a razão
|
| 148 |
-
v16 ≈ 2.8 violava a fronteira estruturalmente, não por qualidade). ∎
|
| 149 |
-
*Verificação: L_normalizada = L_soma/d com erro < 1e-6 (suíte v17 §3).*
|
| 150 |
-
|
| 151 |
-
### Teorema 29.6 (limiar de sucesso invariante à escala)
|
| 152 |
-
|
| 153 |
-
O limiar v16 $\|e\|_2 < 1$ com $\|\text{alvo}\|_2 = \sqrt d = 8$ exige
|
| 154 |
-
erro relativo $< 1/\sqrt d = 0.125$ desde o 1º passo — com predictor
|
| 155 |
-
recém-nascido, taxa $\equiv 0$ (medido), e a tabela de μ (Teo 5.6) fica
|
| 156 |
-
CEGA (μ nunca se adapta). **Cura**: limiar relativo
|
| 157 |
-
|
| 158 |
-
$$\|e\|_2^2 \le \theta\,\|\text{alvo}\|_2^2, \quad \theta = 0.5.$$
|
| 159 |
-
|
| 160 |
-
**Homogeneidade**: para todo $c > 0$,
|
| 161 |
-
$\|c e\|^2 \le \theta \|c\,\text{alvo}\|^2 \iff \|e\|^2 \le \theta\|\text{alvo}\|^2$
|
| 162 |
-
— a taxa não depende da norma do latente (só da direção); uma predição
|
| 163 |
-
proporcional ao alvo com fator $\sqrt\theta$ passa QUALQUER que seja a
|
| 164 |
-
escala do encoder. ∎
|
| 165 |
-
*Verificação: taxa 0.000 → 1.000 após 300 passos Adam em entrada
|
| 166 |
-
predizível; invariante a $c = 50$ (suíte v17 §3).*
|
| 167 |
-
|
| 168 |
-
### Teorema 29.7 (a taxa invariante alimenta a tabela de μ)
|
| 169 |
-
|
| 170 |
-
Com a taxa real $s_t > 0$ (Teo 29.6), a média móvel
|
| 171 |
-
$\bar s_t$ entra em $\mu_t = \mu_{max}^{(1-\bar s_t)}\mu_{min}^{\bar s_t}$
|
| 172 |
-
(Teo 5.6) e o EMA do alvo responde ao progresso REAL do predictor — o
|
| 173 |
-
loop preditor↔alvo volta a ser governado por medida, não por placeholder.
|
| 174 |
-
∎ *Verificação: `jepa/taxa_sucesso` ≥ 0 e μ_efetivo vivo no treino real.*
|
| 175 |
-
|
| 176 |
-
### Teorema 29.8 (λ_jepa autorregulado pela razão PONDERADA)
|
| 177 |
-
|
| 178 |
-
O RM do λ_jepa usa a razão PONDERADA $r_t = \lambda_t L_t / \mathrm{CE}_t$
|
| 179 |
-
(não $L_t/\mathrm{CE}_t$): com a normalização L/d, $\lambda_t L_t$ é a
|
| 180 |
-
contribuição REAL do JEPA ao gradiente total; a fronteira $r \le 1/2$ do
|
| 181 |
-
Teo 28.7-ii mantém a CE como descida primária. Como $r_t$ é medido na
|
| 182 |
-
mesma cadência do RM (Σa = ∞, Σa² < ∞), λ_jepa converge ao ponto onde a
|
| 183 |
-
razão cruza o alvo — equilíbrio na fronteira, sem pêndulo. ∎
|
| 184 |
-
*Verificação: `_razoes_aux["jepa"]` registrado (0.005 na suíte §7);
|
| 185 |
-
controlador "jepa" vivo no autorregulador.*
|
| 186 |
-
|
| 187 |
-
### Regra operacional (doc 28 §9 atualizada)
|
| 188 |
-
|
| 189 |
-
A leitura honesta do A/B v16 ("JEPA puxava a perda total") era o Teo
|
| 190 |
-
28.7-ii VIOLADO pela escala ∝ d. Com L/d + limiar invariante + λ
|
| 191 |
-
autorregulado pela razão ponderada, a contribuição auxiliar volta a ser
|
| 192 |
-
≤ 50% da CE POR CONSTRUÇÃO — o λ default sobe para 7.5
|
| 193 |
-
($\approx 0.117$ em unidades v16) e o controlador cuida do resto.
|
| 194 |
-
|
| 195 |
-
---
|
| 196 |
-
|
| 197 |
-
## 3. jepa_validator — o bloco de predição CTHONIANO
|
| 198 |
-
|
| 199 |
-
### Teorema 29.10 (registro em aritmética C)
|
| 200 |
-
|
| 201 |
-
`JEPAManager.register_variant` acumula `total_params` em `long long`
|
| 202 |
-
nativo (sem boxing Python): a soma de $k$ variantes é exata enquanto
|
| 203 |
-
$\texttt{total} < 2^{63}$ — para qualquer modelo real. `verify_all`
|
| 204 |
-
recalcula o total em laço C e compara ao registrado (auditoria de
|
| 205 |
-
integridade do dict); `compute_parameter_distribution` devolve array
|
| 206 |
-
NumPy float64 **contíguo** com Σ = 1 (variante ausente ⟹ vazio, nunca
|
| 207 |
-
NaN). Contagens negativas são rejeitadas ANTES da acumulação (contrato
|
| 208 |
-
de monotonia). ∎ *Verificação: suíte v17 §4 (93,800 exato; Σ=1
|
| 209 |
-
1e-12; ValueError nos negativos).*
|
| 210 |
-
|
| 211 |
-
### Teorema 29.11 (Token Rounding EXATO — GEMM estofado bit-exato)
|
| 212 |
-
|
| 213 |
-
No bloco de predição, o número de tokens é arredondado ao múltiplo do
|
| 214 |
-
tile τ: $n̂ = \tau\lceil n/\tau\rceil$, razão de estofamento
|
| 215 |
-
$\rho = n̂/n$, estofamento POR CAUDA (offsets = identidade; as linhas
|
| 216 |
-
extras são zeros). Propriedade: **out[t] = Σ_d X[t,d]·W[k,d] é
|
| 217 |
-
independente por linha** — acrescentar linhas nulas adiciona linhas de
|
| 218 |
-
saída nulas e preserva BIT-A-BIT as linhas vivas (mesma ordem de
|
| 219 |
-
acumulação do kernel por linha). Custo: $\rho - 1 \le (\tau-1)/n$
|
| 220 |
-
($\tau \mid n \Rightarrow \rho = 1$). O tile alinha o acesso IO da GEMM
|
| 221 |
-
(SonicMoE tile-aware) SEM mudar o resultado. `escolher_tile` minimiza o
|
| 222 |
-
custo efetivo $t(\tau)\cdot\rho(\tau)$ medido. ∎
|
| 223 |
-
*Verificação: n̂/ρ exatos; GEMM estofado ≡ GEMM nas linhas vivas
|
| 224 |
-
(torch.equal); τ* por medição (suíte v17 §4).*
|
| 225 |
-
|
| 226 |
-
### Teorema 29.12 (auditoria de memória em tempo real — I1–I4)
|
| 227 |
-
|
| 228 |
-
`AuditoriaMemoriaSonic` lê `/proc/self/statm` nível C (~µs; custo
|
| 229 |
-
insignificante por passo) e mantém janelas em ARRAYS C FIXOS (a própria
|
| 230 |
-
auditoria não aloca — dogfooding de I1):
|
| 231 |
-
|
| 232 |
-
- **I1 não-vazamento (Teo 29.12-c, calibrado)**: vazamento = crescimento
|
| 233 |
-
MONOTÔNICO — **mediana** do último terço vs mediana do primeiro terço
|
| 234 |
-
$> 4$ MB **E** inclinação recente $> 0.5$ MB/amostra. MEDIANAS (não
|
| 235 |
-
médias): a variação legítima de tamanho de lote OSCILA (medianas
|
| 236 |
-
convergem); um vazamento cresce TODA amostra (medianas separam). O
|
| 237 |
-
aquecimento legítimo que plateaua não reprova (reancoragem `rebase()`
|
| 238 |
-
1× pelo treinador no passo 20). Corrida real calibrada: crescimento
|
| 239 |
-
0.89 MB (verde) com lotes multimodais heterogêneos.
|
| 240 |
-
- **I2 recompute ≤ fwd (calibrado)**: anomalia REAL de recompute é de
|
| 241 |
-
ESCALA — fugir do checkpoint = memória O(L) inteira ≈ 10–100× o
|
| 242 |
-
forward. Folga $2.5\times + 192$ MB (a janela de recompute inclui a
|
| 243 |
-
alocação legítima de gradientes e a variação de lote).
|
| 244 |
-
- **I3 sem transiente de empilhamento (calibrado)**: entre
|
| 245 |
-
`pilha_ini/pilha_fim` o RSS não excede pico_fwd $\times 2 + 128$ MB —
|
| 246 |
-
o stack de subclass materializaria transiente $N\!f d$ extra; o pool
|
| 247 |
-
indexado (Teo 29.2) não; lotes heterogêneos variam bem menos que a
|
| 248 |
-
folga de escala.
|
| 249 |
-
- **I4 só ativos**: amostras $(A, \Delta\mathrm{RSS})$ provam que a
|
| 250 |
-
memória segue os experts ATIVOS, não $N$ (verificação por regressão na
|
| 251 |
-
suíte).
|
| 252 |
-
|
| 253 |
-
*Verificação: I1–I4 verdes em passos reais do treinador (suíte v17 §7
|
| 254 |
-
com texto; A/B real multimodal com crescimento 0.89 MB — verde);*
|
| 255 |
-
vazamento sintético (240 MB em 60 amostras, malloc direto) REPROVADO
|
| 256 |
-
pelo I1 — "auditoria que nunca reprova não audita".*
|
| 257 |
-
|
| 258 |
-
---
|
| 259 |
-
|
| 260 |
-
## 4. ReplaySSM — memória por recomputação com gradiente exato
|
| 261 |
-
|
| 262 |
-
### Teorema 29.13 (saída e h_L BIT-EXATOS por replay de fronteira)
|
| 263 |
-
|
| 264 |
-
A sequência é dividida em $S$ segmentos; cada segmento $s$ roda a MESMA
|
| 265 |
-
recorrência trapezoidal partindo do estado fronteira $h_{s-1}$:
|
| 266 |
-
|
| 267 |
-
$$h_t = \alpha_t h_{t-1} + \mathrm{entrada}_t, \qquad h_{s\cdot L_s} = h_{s-1}\big|_{\text{fronteira}}.$$
|
| 268 |
-
|
| 269 |
-
Por indução em $t$: se $h_{(s-1)L_s}$ do replay é o valor EXATO do kernel
|
| 270 |
-
completo (fronteira exata anterior + mesma recorrência + mesmos
|
| 271 |
-
operandos), então todo $h_t$ do replay é o valor exato ⟹ **out** e
|
| 272 |
-
**h_L** bit-exatos vs `varredura_trapezoidal` (diferença medida 0.0).
|
| 273 |
-
`h_inicial=None` ⟹ $h_0 = 0$ = v12 exato (nascimento neutro). ∎
|
| 274 |
-
*Verificação: torch.equal nas duas quantidades; S=1 ≡ kernel.*
|
| 275 |
-
|
| 276 |
-
### Teorema 29.14 (gradiente exato e memória O(S·BDN + L_s·BDN))
|
| 277 |
-
|
| 278 |
-
Com `checkpoint(use_reentrant=False)` por segmento e a fronteira levando
|
| 279 |
-
grad_fn (SEM detach), o grafo cruza as fronteiras e a recomputação no
|
| 280 |
-
backward é DETERMINÍSTICA (mesmos operandos, kernels CPU
|
| 281 |
-
determinísticos) ⟹ $\nabla = \nabla_{\text{autograd}}$ do kernel completo
|
| 282 |
-
(erro medido 0.0). Memória: os intermediários do laço temporal por
|
| 283 |
-
segmento são libertados no forward e recomputados no backward —
|
| 284 |
-
ativações guardadas $O(S\cdot BDN + L_s\cdot BDN)$ vs $O(L\cdot BDN)$;
|
| 285 |
-
para $L \gg L_s$ a razão tende a $S/L$. ∎
|
| 286 |
-
*Verificação: erro de gradiente 0.0 (suíte v17 §5); cfg
|
| 287 |
-
`mamba3.replay_segmento` chega às camadas (5 Mamba3Camada no tronco).*
|
| 288 |
-
|
| 289 |
-
---
|
| 290 |
-
|
| 291 |
-
## 5. Integração no treinador (tudo VIVO)
|
| 292 |
-
|
| 293 |
-
| mecanismo | cfg | nascimento | telemetria |
|
| 294 |
-
|---|---|---|---|
|
| 295 |
-
| pools MoE | `modelo.torchao.empacotar_moe` / `n_blocos_floresta` | ausente ⟹ forward v16 | `torchao/moe_compressao` |
|
| 296 |
-
| TCE normalizada | `treino.jepa.normalizar_dim` / `taxa_theta` | True/0.5 | `jepa/perda` (O(1)), `jepa/perda_soma` (compat) |
|
| 297 |
-
| λ_jepa ponderado | automático (Teo 29.8) | escala 1.0 | `autorreg/lambda_jepa` |
|
| 298 |
-
| ReplaySSM | `modelo.mamba3.replay_segmento` (0 = v12) | 0 | — (bit-exato por construção) |
|
| 299 |
-
| auditoria I1–I4 | `treino.auditoria_sonic.ativo` | ligada | `sonic/*` no Hub a cada 100 passos |
|
| 300 |
-
| multi-método | `treino.multi` (doc 30) | escalas 1.0 | `multi/*` (15 controladores) |
|
| 301 |
-
|
| 302 |
-
---
|
| 303 |
-
|
| 304 |
-
## 6. A/B pareado real (corpus 903, vocab 16384, 30 passos, lote 4)
|
| 305 |
-
|
| 306 |
-
| variante | perda início → fim | melhoria | held-out FP32 |
|
| 307 |
-
|---|---|---|---|
|
| 308 |
-
| baseline_v16 (semântica v16: perda SOMA, limiar absoluto) | 9.727 → 9.374 | **1.038×** | 9.774 |
|
| 309 |
-
| v17_khmambajepa (L/d + limiar θ + MULTI + ReplaySSM S=16) | 9.729 → 9.301 | **1.046×** | 9.769 |
|
| 310 |
-
|
| 311 |
-
(Réplica anterior com outro sorteio da mistura: base 1.008× vs v17
|
| 312 |
-
1.039× — a ordem CE troca com o sorteio em 30 passos: PARIDADE; a
|
| 313 |
-
decisão é da corrida 9 h.)
|
| 314 |
-
|
| 315 |
-
- **TCE**: v17 perda normalizada **0.54** (v16: 24.96 — redução ~46× por
|
| 316 |
-
construção, Teo 29.5); taxa de sucesso **0.104** (v16: ≡ 0).
|
| 317 |
-
- **torchao + MoE EMPACOTADA**: 260 camadas + 1 MoE (pools), compressão
|
| 318 |
-
**3.92×**, erro rel. 0.39% ≤ cota, **Δperda held-out FP32→int8+pack =
|
| 319 |
-
0.0** (Teo 29.2/28.1 cumpridas em treino real).
|
| 320 |
-
- **Auditoria I1–I4 na corrida real**: I2 ✓, I3 ✓, I4 ✓; I1 INDICATIVO
|
| 321 |
-
(modo_janela="curto": 60 amostras < 200 — o ratchet do alocador em
|
| 322 |
-
lotes heterogêneos é falso-positivo conhecido, Teo 29.12-d;
|
| 323 |
-
crescimento medido 121 MB não é vazamento — é working set ratchetado;
|
| 324 |
-
nas corridas 9 h a janela satura e o teste é definitivo). Na suíte
|
| 325 |
-
controlada (§7) I1 é VERDE e REPROVA vazamento sintético.
|
| 326 |
-
- **τ_qk bisseção**: ℓ_max ≈ 1.5 ≪ faixa ⟹ τ relaxa 100 → 205 (ocioso
|
| 327 |
-
como previsto — Teo 30.7; QK-clip nunca dispara).
|
| 328 |
-
- **Leitura honesta**: 30 passos não decidem CE; o que a v17 compra em
|
| 329 |
-
corrida curta é ESTRUTURAL (MoE quantizada, TCE sã, memória auditada,
|
| 330 |
-
governança viva).
|
| 331 |
-
|
| 332 |
-
---
|
| 333 |
-
|
| 334 |
-
## 7. Verificação v17 (resumo executável)
|
| 335 |
-
|
| 336 |
-
```
|
| 337 |
-
python3 src/khtst/acelerado/run_verification.py # 8 blocos (A–H)
|
| 338 |
-
python3 tests/test_khtst_v17.py # 59 verificações
|
| 339 |
-
python3 patches/verificar_tudo.py # 49 ✓ / 0 ✗
|
| 340 |
-
python3 scripts/21_teste_v17.py --retreinar_tokenizador # vocab 16384
|
| 341 |
-
python3 scripts/21_teste_v17.py --variante baseline_v16 --passos 120
|
| 342 |
-
python3 scripts/21_teste_v17.py --variante v17_khmambajepa --passos 120
|
| 343 |
-
python3 scripts/21_teste_v17.py --relatorio # A/B pareado
|
| 344 |
-
```
|
| 345 |
-
|
| 346 |
-
Regressão v1–v16: TODAS verdes (25/36/✓/37/32/48/44/21/✓/✓/✓/28/27/40/45).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
docs/matematica/30-autoajuste-multi-metodo.md
DELETED
|
@@ -1,266 +0,0 @@
|
|
| 1 |
-
# 30 — KHMAMBAJEPA v17: AUTOAJUSTE MULTI-MÉTODO (RM + PID + BISSEÇÃO) PARA TODOS OS PARÂMETROS FIXOS
|
| 2 |
-
|
| 3 |
-
*Doc matemático da v17, parte 2 — a proposta do requisito (§§1–4)
|
| 4 |
-
transformada em governança EXECUTÁVEL: cada parâmetro fixo de projeto
|
| 5 |
-
(AdamW β₁/β₂/ε/wd, Muon momentum, τ_qk, PRS V8, PESO_MOE,
|
| 6 |
-
PESO_ALINHAMENTO_SOM, margem ABMO, CIAR, crescimento) recebe um
|
| 7 |
-
controlador com recursão híbrida, sinais definidos, limites seguros e
|
| 8 |
-
auditoria integral no TelemetryHub.*
|
| 9 |
-
|
| 10 |
-
---
|
| 11 |
-
|
| 12 |
-
## 0. Escopo e honestidade
|
| 13 |
-
|
| 14 |
-
Cada teorema é acompanhado da verificação empírica da suíte v17 (§6) e,
|
| 15 |
-
quando aplicável, do treino real. Onde o sinal literal do requisito forma
|
| 16 |
-
realimentação POSITIVA (divergência provável), o doc PROVA o problema e
|
| 17 |
-
inverte o sinal mantendo a semântica — com o contraexemplo exposto
|
| 18 |
-
(Teo 30.6). O que NÃO se afirma: que as escalas convergem em 120 passos
|
| 19 |
-
de corrida curta — as constantes aceleradas (a0=0.15, τ_a=60) fazem os
|
| 20 |
-
controladores se MOVAREM visivelmente; a convergência assintótica é o
|
| 21 |
-
enunciado das provas, não a leitura de uma corrida.
|
| 22 |
-
|
| 23 |
-
---
|
| 24 |
-
|
| 25 |
-
## 1. A recursão híbrida unificada
|
| 26 |
-
|
| 27 |
-
### Teorema 30.1 (RM + perturbação determinística limitada: pertença e convergência)
|
| 28 |
-
|
| 29 |
-
Todo parâmetro governado $\theta_t = \exp(u_t)$ com
|
| 30 |
-
|
| 31 |
-
$$u_{t+1} = u_t + a_t s_t + b\,e_t + c_i I_t + c_d \Delta e_t,$$
|
| 32 |
-
|
| 33 |
-
$a_t = a_0/(1+t/\tau_a)$, $|s_t| \le 1$, $|e_t| \le 1$ (canais
|
| 34 |
-
normalizados), $I_t = \mathrm{clip}(0.98\,I_{t-1} + e_t, \pm 1)$
|
| 35 |
-
(vazamento anti-windup), $\Delta e_t = e_t - e_{t-1}$:
|
| 36 |
-
|
| 37 |
-
1. **Pertença**: com truncagem $u \in [\ln \theta_{min}, \ln \theta_{max}]$,
|
| 38 |
-
$\theta_t \in [\theta_{min}, \theta_{max}]$ PARA TODO $t$ — os termos
|
| 39 |
-
PID são limitados por $|b| + |c_i| + |c_d|$ (passo_max clipa o total),
|
| 40 |
-
logo não há escape dos limites;
|
| 41 |
-
2. **Convergência q.c.** (parte RM): $a_t$ satisfaz
|
| 42 |
-
$\sum a_t = \infty$, $\sum a_t^2 < \infty$ (condição clássica de
|
| 43 |
-
Robbins–Monro, Teo 28.5) — o ruído de medida é médio e o iterante
|
| 44 |
-
converge q.c. ao conjunto estacionário do campo de deriva;
|
| 45 |
-
3. **O PID não quebra 2** (duas escalas, Borkar): com ganhos $b, c_i, c_d$
|
| 46 |
-
O(1) e $a_t \to 0$, o canal PID opera em escala de tempo MAIS RÁPIDA —
|
| 47 |
-
ele leva $e_t \to 0$ (loop negativo do Teo 30.2) e o resíduo
|
| 48 |
-
assintótico do RM é o equilíbrio $e = 0$ do campo médio;
|
| 49 |
-
4. **Anti-windup**: com vazamento 0.98, $I_t$ é mapeamento contratativo
|
| 50 |
-
no erro ($|I_t| \le 1$) — o integrador não retém memória ilimitada. ∎
|
| 51 |
-
|
| 52 |
-
*Verificação: 2000 passos com sinais máximos ⟹ θ ∈ [θ_min, θ_max]
|
| 53 |
-
sempre; integral satura exatamente em 1.0 (suíte v17 §6).*
|
| 54 |
-
|
| 55 |
-
### Teorema 30.2 (estabilidade do loop proporcional em log-escala)
|
| 56 |
-
|
| 57 |
-
Seja a medida $m(\theta)$ monotônica em $\theta$ com ponto alvo $m^*$ e
|
| 58 |
-
erro $e(\theta) = \pm(m^* - m(\theta))/\mathrm{norm}$ com SINAL escolhido
|
| 59 |
-
de modo que $e \cdot (\theta - \theta^*) < 0$ (realimentação NEGATIVA).
|
| 60 |
-
Linearizando em $u = \ln\theta$: $\Delta u_t \approx a\, k\, (u_t - u^*)$
|
| 61 |
-
com $k = \partial e/\partial \ln\theta > 0$ — o loop discreto é estável
|
| 62 |
-
sse $|1 - a k| < 1$, i.e.
|
| 63 |
-
|
| 64 |
-
$$a_0\, k < 2 \quad (\text{na pior cadência do decaimento}).$$
|
| 65 |
-
|
| 66 |
-
Todos os controladores abaixo têm a condição verificada analiticamente
|
| 67 |
-
(k explícito) — valem com os defaults e com as constantes aceleradas das
|
| 68 |
-
corridas curtas. ∎
|
| 69 |
-
|
| 70 |
-
---
|
| 71 |
-
|
| 72 |
-
## 2. AdamW: β₁, β₂, ε, weight_decay (requisito §3.1)
|
| 73 |
-
|
| 74 |
-
### Teorema 30.3 (β₂ por variância do gradiente; β₁ pela tendência)
|
| 75 |
-
|
| 76 |
-
Métrica: $CV^2 = \mathrm{Var}[\|g\|]/E[\|g\|]^2$ sobre a janela (proxy de
|
| 77 |
-
curvatura/ruído). Sinais:
|
| 78 |
-
- $\beta_2$: $s = \frac{CV^2_{\text{alvo}} - CV^2}{CV^2_{\text{alvo}} + CV^2}$
|
| 79 |
-
— variância ALTA ⟹ ruído domina ⟹ β₂ DESCE (média móvel mais curta,
|
| 80 |
-
mais adaptativa — o 2º momento acompanha o regime); variância baixa ⟹
|
| 81 |
-
β₂ sobe (suavização). Monotonia: ∂CV²/∂(regime) > 0 e a escala β₂
|
| 82 |
-
multiplica o β de projeto ⟹ resposta monótona (Teo 30.2) com
|
| 83 |
-
$k \le 1$ ⟹ $a_0 < 2$ ✓.
|
| 84 |
-
- $\beta_1$: $s = -\mathrm{tend}(CV^2)$ — tendência de ALTA ⟹ β₁ desce
|
| 85 |
-
(menos momentum no 1º momento = mais reatividade ao novo regime);
|
| 86 |
-
queda ⟹ β₁ sobe. ∎
|
| 87 |
-
|
| 88 |
-
*Verificação: CV²=4 sustentado ⟹ β₂ escala → piso 0.9 (suíte v17 §6);
|
| 89 |
-
no treino real β₂=1.0 no nascimento (Teo 30.1) e vivo na cadência.*
|
| 90 |
-
|
| 91 |
-
### Teorema 30.4 (ε pela razão update/gradiente)
|
| 92 |
-
|
| 93 |
-
Sinal do requisito: $\rho_t = \|\Delta p\|/\|g\|$ (medido em amostra fixa
|
| 94 |
-
de ≤12 parâmetros, custo O(amostra)). ε entra no denominador do passo
|
| 95 |
-
AdamW: $\varepsilon \uparrow \Rightarrow$ passo ↓. Loop correto: ρ acima
|
| 96 |
-
do alvo 1.0 (updates grandes relativos ao gradiente — risco) ⟹ ε sobe
|
| 97 |
-
(amortece); ρ baixo ⟹ ε desce (passo mais cheio). Sinal
|
| 98 |
-
$s = \frac{\rho - 1}{\rho + 1}$ com ∂ρ/∂ε < 0 ⟹ realimentação negativa;
|
| 99 |
-
$k \le 1$ ⟹ estável (Teo 30.2). ∎
|
| 100 |
-
|
| 101 |
-
### Teorema 30.5 (weight_decay com norma RELATIVA — o alvo absoluto 1.0 é infactível)
|
| 102 |
-
|
| 103 |
-
**Lema (infactibilidade)**: com RMS(W_init) ≈ 0.02 (tabelas/embeddings),
|
| 104 |
-
exigir $\|W\| = 1.0$ absoluto pediria crescimento de 50× — o wd explodiria
|
| 105 |
-
no nascimento. **Forma relativa**: $\bar n_t = \mathbb{E}_\text{amostra}
|
| 106 |
-
[\|W\|/\|W_0\|]$ (invariante à escala de cada tensor — prova: multiplicar
|
| 107 |
-
W₀ por c multiplica numerador e denominador). Sinal $e = \mathrm{clip}(\bar n - 1)$:
|
| 108 |
-
norma relativa acima do nascimento ⟹ wd sobe (puxa de volta); abaixo ⟹
|
| 109 |
-
wd desce. Loop: ∂n̄/∂wd < 0 (decay encolhe W) ⟹ negativo; k = 1 ⟹ estável
|
| 110 |
-
com $a_0 < 2$. ∎
|
| 111 |
-
|
| 112 |
-
---
|
| 113 |
-
|
| 114 |
-
## 3. Muon: momentum e τ_qk (requisito §3.2)
|
| 115 |
-
|
| 116 |
-
### Teorema 30.6 (momentum — o sinal literal DIVERGE; o inverso converge)
|
| 117 |
-
|
| 118 |
-
A razão $\rho_m = \|buf\|/\|g\|$ satisfaz $\rho_m \approx \beta/(1-\beta)$
|
| 119 |
-
em regime (buf = Σβ^i g). **Contraexemplo do sinal literal**
|
| 120 |
-
($s = \rho_m - \rho^*$): no equilíbrio $\rho_m = \rho^*$; uma flutuação
|
| 121 |
-
$\rho_m \uparrow$ dá $s > 0$ ⟹ β ↑ ⟹ $\rho_m \uparrow$ (monotônico) —
|
| 122 |
-
realimentação POSITIVA, escape para o teto. **Sinal correto**
|
| 123 |
-
$s = \rho^* - \rho_m$: loop negativo. Estabilidade em log-escala:
|
| 124 |
-
$\frac{\partial \rho_m}{\partial \ln\beta} = \frac{\beta}{1-\beta}$ — no
|
| 125 |
-
piso β=0.9 (escala mínima 0.9×0.95) vale ≈ 19 ⟹ condição do Teo 30.2:
|
| 126 |
-
$a_0 \cdot 19 < 2 \Rightarrow a_0 < 0.105$ ✓ (default 0.05; acelerada
|
| 127 |
-
0.15 é marginal e o passo_max=0.05 clipa o du/dt — pertença garantida
|
| 128 |
-
pelo Teo 30.1). ∎
|
| 129 |
-
*Verificação: razão baixa sustentada ⟹ momentum escala → teto 1.05.*
|
| 130 |
-
|
| 131 |
-
### Teorema 30.7 (τ_qk por bisseção — erro ≤ (τ_max−τ_min)/2^k)
|
| 132 |
-
|
| 133 |
-
τ_qk só afeta o modelo pelo QK-clip pós-step ($\gamma = \tau/\ell_{max}$
|
| 134 |
-
quando $\ell_{max} > \tau$; Teo 24.7 — o logit é LINEAR em W_q) ⟹
|
| 135 |
-
$\partial \ell_{max}(t{+}1)/\partial \tau(t) \ge 0$ (resposta monótona).
|
| 136 |
-
Malha: $\ell_{max} > \text{hi}$ por `paciencia` observações ⟹ descarta a
|
| 137 |
-
metade SUPERIOR do intervalo ($\tau_{max} \leftarrow \tau$,
|
| 138 |
-
$\tau \leftarrow (\tau_{min}+\tau)/2$); $\ell_{max} < $ lo ⟹ metade
|
| 139 |
-
inferior. A cada ajuste o intervalo contrai 1/2: após k ajustes,
|
| 140 |
-
$\tau$ está a $\le (\tau_{max}^0 - \tau_{min}^0)/2^k$ da raiz. Com RCO
|
| 141 |
-
ativo (Teo 27.2: $\ell_{max} \le d/\sqrt{dh}$ estrutural < faixa), o
|
| 142 |
-
controlador é NATURALMENTE OCIOSO — só atua quando $\ell_{max}$ realmente
|
| 143 |
-
excede a faixa (a bisseção relaxa τ até o teto; o clip segue inativo). ∎
|
| 144 |
-
*Verificação: ℓ_max=200 sustentado ⟹ τ 100→60→40→30 com intervalo
|
| 145 |
-
contraindo (suíte v17 §6).*
|
| 146 |
-
|
| 147 |
-
---
|
| 148 |
-
|
| 149 |
-
## 4. PRS V8 (requisito §3.3) e pesos de perdas (§3.4)
|
| 150 |
-
|
| 151 |
-
### Teorema 30.8 (η_up/η_down com ponto fixo EXATO do trust)
|
| 152 |
-
|
| 153 |
-
Do doc 11 (7.1): $E[T_\infty] = \dfrac{p\,\eta_{up}}{p\,\eta_{up} + (1-p)\,\eta_{down}}$
|
| 154 |
-
— CRESCENTE em η_up e DECRESCENTE em η_down. Controladores com sinais
|
| 155 |
-
opostos sobre o MESMO erro $e_T = T^* - T$: η_up segue $+e_T$ (trust
|
| 156 |
-
baixo ⟹ recupera mais rápido), η_down segue $-e_T$ (trust alto ⟹ decai
|
| 157 |
-
mais rápido). Ambos os loops são negativos (∂T∞/∂η_up > 0,
|
| 158 |
-
∂T∞/∂η_down < 0) e o ponto fixo conjunto é a curva
|
| 159 |
-
$E[T_\infty] = T^*$ — equilíbrio EXATO em termos da taxa real de acertos
|
| 160 |
-
$p$. ∎
|
| 161 |
-
|
| 162 |
-
### Teorema 30.9 (T_ciclo e decay_piso pela velocidade de convergência)
|
| 163 |
-
|
| 164 |
-
$v_t$ = Δperda/passo padronizada. $s_{ciclo} = \frac{v - v^*}{|v| + v^*}$:
|
| 165 |
-
progresso acima do alvo ⟹ ciclo ↑ (refinamento mais longo); estagnação ⟹
|
| 166 |
-
ciclo ↓ (reinícios SGDR mais frequentes = exploração). $s_{piso} = -s_{ciclo}$:
|
| 167 |
-
estagnação ⟹ piso RETIDO (decay_piso ↑ — mais energia de exploração nos
|
| 168 |
-
reinícios); progresso ⟹ piso cai (menos energia — já convergiu). Monotonia:
|
| 169 |
-
T_ciclo e decay_piso são coeficientes DIRETOS do cronograma (resposta
|
| 170 |
-
identidade) ⟹ k=1, estável. ∎
|
| 171 |
-
|
| 172 |
-
### Teorema 30.10 (percentil pela fração de clipagem)
|
| 173 |
-
|
| 174 |
-
$\mathrm{clip}(t) = Q_{\text{percentil}}(\text{janela de } \|g\|)$ ⟹
|
| 175 |
-
$\partial \mathrm{frac\_clip}/\partial\,\text{percentil} < 0$ (quantil
|
| 176 |
-
maior = limiar maior = menos gradientes clipados). Sinal
|
| 177 |
-
$s = \frac{\mathrm{frac} - \mathrm{frac}^*}{\mathrm{frac}^*}$ com
|
| 178 |
-
$\mathrm{frac}^* = 0.10$: muitos clipados ⟹ percentil ↑ (menos clipping);
|
| 179 |
-
poucos ⟹ ↓. Loop negativo com inclinação ≤ 1 ⟹ estável. ∎
|
| 180 |
-
|
| 181 |
-
### Teorema 30.11 (PESO_MOE — CE dominante por construção)
|
| 182 |
-
|
| 183 |
-
Sinal $s = \mathrm{clip}(\tfrac12 - L_{moe}/\mathrm{CE})$: razão acima de
|
| 184 |
-
½ ⟹ peso DESCE (a perturbação do gradiente CE pela perda auxiliar fica
|
| 185 |
-
≤ 50% — mesma fronteira do Teo 28.7-ii canônico). Nota de convenção: o
|
| 186 |
-
sinal literal do requisito $(\text{razão} - ½)$ assume RM que DESCE com
|
| 187 |
-
sinal positivo; no `ControladorHibrido` sinal > 0 sobe θ — a direção de
|
| 188 |
-
controle é idêntica (doc 29 §2). O controlador soma-se ao Teo 28.7-ii
|
| 189 |
-
(mesmo sinal, ganho efetivo ~2× — dentro da família RM, Teo 28.5
|
| 190 |
-
independe de ganho constante). ∎
|
| 191 |
-
|
| 192 |
-
### Teorema 30.12 (PESO_ALINHAMENTO_SOM por ativação; e o Lema da não-identificabilidade)
|
| 193 |
-
|
| 194 |
-
Loop: $e_s = \frac{0.9 - \text{taxa\_ativa}}{0.9}$ com PID (P+I) —
|
| 195 |
-
ativação abaixo do alvo 90% ⟹ peso ↑ (recruta neurônios aos protótipos
|
| 196 |
-
da memória). Monotonia assumida e monitorada (a telemetria registra a
|
| 197 |
-
correlação; sem monotonia o Teo 30.1 garante apenas PERTENÇA — honesto).
|
| 198 |
-
|
| 199 |
-
**Lema 30.12-b (não-identificabilidade autorreferente)**: os parâmetros
|
| 200 |
-
do PRS que DEFINEM a métrica do seu próprio controlador
|
| 201 |
-
(`coef_streak`, `vel_alvo`, `boost_max`, `alfa_sig` — o boost é
|
| 202 |
-
$\sigma(\alpha(\bar v - v_{alvo}))$) não podem ser regulados PELA MESMA
|
| 203 |
-
métrica: mover `vel_alvo` com dados de $\bar v$ desloca o zero do sinal e
|
| 204 |
-
o controlador persegue o próprio alvo móvel (loop circular sem âncora
|
| 205 |
-
exógena ⟹ sem ponto fixo definido). Permanecem FIXOS por projeto. ∎
|
| 206 |
-
|
| 207 |
-
---
|
| 208 |
-
|
| 209 |
-
## 5. ABMO, CIAR, crescimento (requisito §3.5) e integração
|
| 210 |
-
|
| 211 |
-
### Teorema 30.13 (margem ABMO — equilíbrio na borda da barreira)
|
| 212 |
-
|
| 213 |
-
A barreira $\eta_{alvo} = (2-m)/\hat L$ garante descida (Teos 10.11/24.9)
|
| 214 |
-
com $\eta \le \eta_{alvo}$ SEMPRE (min estrutural). Sinal
|
| 215 |
-
$s = \mathrm{clip}(\eta/\eta_{alvo} - 1) \le 0$: barreira ATIVA (folga
|
| 216 |
-
negativa) ⟹ margem $m$ desce ⟹ $\eta_{alvo} \uparrow$ ⟹ folga → 0⁻.
|
| 217 |
-
Ponto fixo: a borda da barreira (η alivia até o lr composto caber) — a
|
| 218 |
-
garantia de descida vale em TODO passo (o min nunca é relaxado além do
|
| 219 |
-
cap). Loop: ∂η_alvo/∂m < 0 ⟹ negativo. ∎
|
| 220 |
-
|
| 221 |
-
### Teorema 30.14 (CIAR é o canal derivativo do lr — dois multiplicadores inflam a variância)
|
| 222 |
-
|
| 223 |
-
O κ do CIAR já é PID (ganho + integral com vazamento, Teo 20.4). A
|
| 224 |
-
integração v17 NÃO adiciona um 3º multiplicador de lr: dois
|
| 225 |
-
multiplicadores independentes $s_1, s_2$ dão
|
| 226 |
-
$E[(s_1 s_2)^2] = E[s_1^2]\,E[s_2^2] > E[s_1^2]$ (independência) — a
|
| 227 |
-
variância do passo efetivo INFLA e o RM do lr (Teo 28.7-i) perde a
|
| 228 |
-
condição de 2º momento. O multi-método atua nos HIPERPARÂMETROS
|
| 229 |
-
(β/ε/wd/momentum) e deixa o lr com seus dois canais canônicos (RM v16 +
|
| 230 |
-
κ CIAR). ∎
|
| 231 |
-
|
| 232 |
-
### Teorema 30.15 (crescimento — equilíbrio expansão/poda em log-razão)
|
| 233 |
-
|
| 234 |
-
Sinal $s = \mathrm{clip}(\ln \frac{r_{exp}}{r_{prune}})$ (razão suavizada
|
| 235 |
-
por Laplace $+1$): mais expansão que poda ⟹ escala ↑ ⟹ τ_expand ↑ e
|
| 236 |
-
τ_prune ↓ (expande mais fácil, poda mais difícil); o inverso reequilibra.
|
| 237 |
-
Ponto fixo: $r_{exp} = r_{prune}$ (equilíbrio estrutural). Loop: ∂(razão)/∂τ_expand > 0
|
| 238 |
-
e ∂(razão)/∂τ_prune < 0 ⟹ negativo. ∎
|
| 239 |
-
|
| 240 |
-
### 5.1 Integração e auditoria (requisito §4)
|
| 241 |
-
|
| 242 |
-
- Um `ControladorHibrido` (ou `BissecaoTauQK`) POR parâmetro — 15
|
| 243 |
-
controladores — criados com limites seguros e nascimento NEUTRO (1.0);
|
| 244 |
-
- Sinais conforme a tabela acima; TODAS as métricas registradas no
|
| 245 |
-
TelemetryHub (`multi/*` a cada 100 passos; `sonic/*`; `autorreg/*`);
|
| 246 |
-
- Aplicação MULTIPLICATIVA sobre os valores-base de projeto (`definir_bases`)
|
| 247 |
-
— os defaults de projeto permanecem intactos e o A/B é limpo;
|
| 248 |
-
- O canal PID existe onde o requisito pede resposta a tendências
|
| 249 |
-
(β₁, wd, η_up/down, peso_som) — proporcional + integral com vazamento;
|
| 250 |
-
o derivativo entra por Δe nos controladores com resposta a regime
|
| 251 |
-
(β₁).
|
| 252 |
-
|
| 253 |
-
---
|
| 254 |
-
|
| 255 |
-
## 6. Verificação (resumo executável)
|
| 256 |
-
|
| 257 |
-
```
|
| 258 |
-
python3 tests/test_khtst_v17.py # §6 da suíte: Teos 30.1–30.15
|
| 259 |
-
python3 src/khtst/acelerado/run_verification.py # bloco H
|
| 260 |
-
```
|
| 261 |
-
|
| 262 |
-
Cobertura empírica: nascimento neutro; loops β₂/ε/wd/momentum/η/PESO_MOE/
|
| 263 |
-
PESO_SOM/ABMO/crescimento com DIREÇÃO correta e limites; bisseção τ_qk
|
| 264 |
-
contração 1/2; anti-windup; truncagem sempre; escalas chegam ao
|
| 265 |
-
otimizador (hiperparâmetros efetivos = base × escala com clamps); treino
|
| 266 |
-
real com 15 controladores vivos e telemetria completa.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
graficos/v17/v17_evidencias.png
DELETED
Git LFS Details
|
patches/jepa.py
CHANGED
|
@@ -116,9 +116,6 @@ class ConfigJepa:
|
|
| 116 |
# NASCIMENTO NEUTRO — vicreg_lambda=0 ⟹ perda idêntica à v15.1.
|
| 117 |
vicreg_lambda: float = 0.0
|
| 118 |
vicreg_gamma: float = 1.0 # alvo do hinge de variância (σ_j ≥ γ)
|
| 119 |
-
# v17 (doc 29, Teos 29.5–29.9 — Problema 2: perda TCE alta na suíte v16)
|
| 120 |
-
normalizar_dim: bool = True # L ← L/d_latente (Teo 29.5: magnitude ∝ d)
|
| 121 |
-
taxa_theta: float = 0.5 # limiar INVARIANTE ‖e‖² ≤ θ·‖alvo‖² (Teo 29.6)
|
| 122 |
|
| 123 |
|
| 124 |
class PredictorLatente(nn.Module):
|
|
@@ -295,22 +292,7 @@ class MotorJepa(nn.Module):
|
|
| 295 |
if validos.sum() == 0:
|
| 296 |
zero = h.sum() * 0.0
|
| 297 |
return zero, {"jepa/ativo": 0.0}
|
| 298 |
-
# v17 (Teo 29.5 — Problema 2: TCE ~25 na suíte v16). CAUSA: a soma
|
| 299 |
-
# sobre d_latente tem magnitude ∝ d — com latentes esféricos
|
| 300 |
-
# (‖f(x)‖₂ = √d ⟹ E[e_j²] ≈ 1 por componente), E[Huber(e_j)] ≈ c_
|
| 301 |
-
# Huber ∈ (0,1) por componente ⟹ L ≈ c·d (d=64 ⟹ L≈25 MEDIDO).
|
| 302 |
-
# CURA: normalização dimensional L/d — por LINEARIDADE da perda em
|
| 303 |
-
# cada componente, ∇_θ(L/d) = (∇_θ L)/d EXATAMENTE: a regra é uma
|
| 304 |
-
# REPARAMETRIZAÇÃO PURA λ' = λ·d (o mesmo ponto estacionário; a v16
|
| 305 |
-
# é recuperada com λ' = λ_v16·d — prova no doc 29). Ganho: a razão
|
| 306 |
-
# L/CE fica O(1) — comparável entre arquiteturas e com a fronteira
|
| 307 |
-
# ½ do Teo 28.7-ii (a autorregulação RM torna-se BEM DEFINIDA).
|
| 308 |
-
d_lat = pred.shape[-1]
|
| 309 |
L = per_elem.sum(-1)[validos].mean()
|
| 310 |
-
perda_soma = L.detach()
|
| 311 |
-
if cfg.normalizar_dim:
|
| 312 |
-
L = L / d_lat
|
| 313 |
-
perda_base = float(L.detach())
|
| 314 |
|
| 315 |
# v16 — termo VICReg do MC-JEPA via kernel Cython (doc 28 §§6–7):
|
| 316 |
# pred = P (ramo online), lat_alvo = Z (ramo alvo, EMA — sem
|
|
@@ -332,27 +314,14 @@ class MotorJepa(nn.Module):
|
|
| 332 |
vic_tele["jepa/vicreg_colapso"] = frac
|
| 333 |
|
| 334 |
with torch.no_grad():
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
# v17 (Teo 29.6 — causa 2 da TCE): o limiar ABSOLUTO ‖e‖<1 com
|
| 338 |
-
# ‖alvo‖₂ = √d ⟹ taxa_sucesso ≡ 0 para d > 1 (a predição teria
|
| 339 |
-
# que acertar o alvo com erro RELATIVO < 1/√d — impossível no
|
| 340 |
-
# arranque; medido: taxa 0.0 na v16 ⟹ tabela de μ cega).
|
| 341 |
-
# CURA: limiar INVARIANTE à escala — erro relativo ao alvo:
|
| 342 |
-
# ‖e‖² ≤ θ·‖alvo‖² com θ = taxa_theta (0.5).
|
| 343 |
-
# HOMOGENEIDADE: para todo c > 0, ‖c·e‖² ≤ θ·‖c·alvo‖² ⟺
|
| 344 |
-
# ‖e‖² ≤ θ·‖alvo‖² — a taxa não depende da norma do latente,
|
| 345 |
-
# apenas da direção: uma predição proporcional ao alvo com fator
|
| 346 |
-
# √θ passa no limiar QUALQUER que seja a escala do encoder.
|
| 347 |
-
taxa = float((erro2 <= cfg.taxa_theta * alvo2.clamp(min=1e-12))
|
| 348 |
-
.float().mean())
|
| 349 |
self._taxa_sucesso.append(taxa) # correção A: telemetria real
|
| 350 |
var = lat_alvo.var(dim=0).mean()
|
| 351 |
-
self.historico.append(
|
| 352 |
return L, {
|
| 353 |
"jepa/ativo": 1.0,
|
| 354 |
-
"jepa/perda":
|
| 355 |
-
"jepa/perda_soma": float(perda_soma), # soma bruta (compat v16)
|
| 356 |
"jepa/taxa_sucesso": taxa,
|
| 357 |
"jepa/taxa_sucesso_media": self.taxa_sucesso_media(),
|
| 358 |
"jepa/mu_efetivo": self.funil_bar.ultimo_mu,
|
|
|
|
| 116 |
# NASCIMENTO NEUTRO — vicreg_lambda=0 ⟹ perda idêntica à v15.1.
|
| 117 |
vicreg_lambda: float = 0.0
|
| 118 |
vicreg_gamma: float = 1.0 # alvo do hinge de variância (σ_j ≥ γ)
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
|
| 121 |
class PredictorLatente(nn.Module):
|
|
|
|
| 292 |
if validos.sum() == 0:
|
| 293 |
zero = h.sum() * 0.0
|
| 294 |
return zero, {"jepa/ativo": 0.0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
L = per_elem.sum(-1)[validos].mean()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
|
| 297 |
# v16 — termo VICReg do MC-JEPA via kernel Cython (doc 28 §§6–7):
|
| 298 |
# pred = P (ramo online), lat_alvo = Z (ramo alvo, EMA — sem
|
|
|
|
| 314 |
vic_tele["jepa/vicreg_colapso"] = frac
|
| 315 |
|
| 316 |
with torch.no_grad():
|
| 317 |
+
erro = (pred - lat_alvo).norm(dim=-1)[validos]
|
| 318 |
+
taxa = float((erro < 1.0).float().mean())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
self._taxa_sucesso.append(taxa) # correção A: telemetria real
|
| 320 |
var = lat_alvo.var(dim=0).mean()
|
| 321 |
+
self.historico.append(float(L.detach()))
|
| 322 |
return L, {
|
| 323 |
"jepa/ativo": 1.0,
|
| 324 |
+
"jepa/perda": float(L.detach()),
|
|
|
|
| 325 |
"jepa/taxa_sucesso": taxa,
|
| 326 |
"jepa/taxa_sucesso_media": self.taxa_sucesso_media(),
|
| 327 |
"jepa/mu_efetivo": self.funil_bar.ultimo_mu,
|
scripts/21_teste_v17.py
DELETED
|
@@ -1,324 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
"""21_teste_v17.py — TESTE REAL v17 KHMAMBAJEPA (doc 29 §10).
|
| 3 |
-
|
| 4 |
-
Requisitos da rodada v17 verificados com CORPUS REAL e vocab 16384:
|
| 5 |
-
• Problema 1 — MoE EMPACOTADA na quantização (pools/indexador/floresta);
|
| 6 |
-
• Problema 2 — TCE normalizada (L/d) + limiar invariante + λ_jepa
|
| 7 |
-
autorregulado pela razão PONDERADA;
|
| 8 |
-
• ReplaySSM (varredura por segmentos, gradiente exato) no treino real;
|
| 9 |
-
• Autoajuste MULTI-MÉTODO (RM+PID+bisseção) vivo em passos reais;
|
| 10 |
-
• Auditoria de memória I1–I4 em tempo real (Cython).
|
| 11 |
-
|
| 12 |
-
Variantes (UMA por processo):
|
| 13 |
-
A) baseline_v16 — semântica v16 EXATA: JEPA com perda SOMA (L, sem L/d)
|
| 14 |
-
λ=0.5, limiar absoluto ‖e‖<1, autorreg RM v16, sem multi/replay/pools;
|
| 15 |
-
B) v17_khmambajepa — JEPA normalizada λ'=7.5 (Teo 29.5: reparametrização
|
| 16 |
-
λ'=λ·d/…; razão ponderada ≤ ½ pelo Teo 29.8), limiar θ=0.5, MULTI
|
| 17 |
-
ativo (constantes aceleradas p/ corrida curta), ReplaySSM S=16,
|
| 18 |
-
torchao + EMPACOTAMENTO MoE na inferência final.
|
| 19 |
-
|
| 20 |
-
Uso:
|
| 21 |
-
python3 scripts/21_teste_v17.py --retreinar_tokenizador # 1× (vocab 16384)
|
| 22 |
-
python3 scripts/21_teste_v17.py --variante baseline_v16 --passos 120
|
| 23 |
-
python3 scripts/21_teste_v17.py --variante v17_khmambajepa --passos 120
|
| 24 |
-
python3 scripts/21_teste_v17.py --relatorio # consolida A/B
|
| 25 |
-
"""
|
| 26 |
-
from __future__ import annotations
|
| 27 |
-
|
| 28 |
-
import argparse
|
| 29 |
-
import base64
|
| 30 |
-
import json
|
| 31 |
-
import os
|
| 32 |
-
import sys
|
| 33 |
-
|
| 34 |
-
RAIZ = os.environ.get("KHTST_RAIZ", "/home/z/my-project/khtst")
|
| 35 |
-
sys.path.insert(0, os.path.join(RAIZ, "src"))
|
| 36 |
-
|
| 37 |
-
CORPUS = os.path.join(RAIZ, "cache_dados", "corpus_v16.jsonl")
|
| 38 |
-
TOKENIZADOR_V17 = os.path.join(RAIZ, "cache_dados", "tokenizador_v17.json")
|
| 39 |
-
TOKENIZADOR_V16 = os.path.join(RAIZ, "cache_dados", "tokenizador_v16.json")
|
| 40 |
-
METRICAS = os.path.join(RAIZ, "telemetria_out", "metricas_v17")
|
| 41 |
-
|
| 42 |
-
NOVOS_IDS = {"allenai/fetchman-data", "endoard/grab_ball_3cam_skin",
|
| 43 |
-
"SoSolaris/Astra_test_20261005052625",
|
| 44 |
-
"mulligan/sim-square-narrow-c00-teleop-mixed",
|
| 45 |
-
"pltops/evosynth-gsm8k-smoke-cerebras-gsm8k",
|
| 46 |
-
"heatherwhite/math-collection", "HuggingFaceH4/MATH-500",
|
| 47 |
-
"IFM/Math-Reasoning", "EleutherAI/hendrycks_math#algebra",
|
| 48 |
-
"EleutherAI/hendrycks_math#number_theory",
|
| 49 |
-
"open-r1/OpenR1-Math-220k", "IFM/Math-Reasoning#socratic",
|
| 50 |
-
"3DTopia/4DNeX-10M"}
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
def carregar_registros(caminho: str) -> list[dict]:
|
| 54 |
-
registros = []
|
| 55 |
-
if not os.path.exists(caminho):
|
| 56 |
-
return registros
|
| 57 |
-
with open(caminho, encoding="utf-8") as f:
|
| 58 |
-
for linha in f:
|
| 59 |
-
try:
|
| 60 |
-
r = json.loads(linha)
|
| 61 |
-
except Exception:
|
| 62 |
-
continue
|
| 63 |
-
if isinstance(r.get("imagem"), str):
|
| 64 |
-
try:
|
| 65 |
-
r["imagem"] = base64.b64decode(r["imagem"])
|
| 66 |
-
except Exception:
|
| 67 |
-
r["imagem"] = None
|
| 68 |
-
if isinstance(r.get("audio"), str):
|
| 69 |
-
try:
|
| 70 |
-
r["audio"] = base64.b64decode(r["audio"])
|
| 71 |
-
except Exception:
|
| 72 |
-
r["audio"] = None
|
| 73 |
-
registros.append(r)
|
| 74 |
-
return registros
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
def retreinar_tokenizador(vocab: int = 16384) -> dict:
|
| 78 |
-
"""REQUISITO v17: vocab 16384 mantido — tokenizador RETREINADO no corpus
|
| 79 |
-
real com o vocabulário do requisito (prefixos [robo]/ath] especiais)."""
|
| 80 |
-
from khtst.dados.tokenizador import TokenizadorKHTST
|
| 81 |
-
registros = carregar_registros(CORPUS)
|
| 82 |
-
|
| 83 |
-
def textos():
|
| 84 |
-
for r in registros:
|
| 85 |
-
if r.get("texto"):
|
| 86 |
-
yield r["texto"]
|
| 87 |
-
if r.get("entrada"):
|
| 88 |
-
yield r["entrada"]
|
| 89 |
-
if r.get("saida"):
|
| 90 |
-
yield r["saida"]
|
| 91 |
-
|
| 92 |
-
tk = TokenizadorKHTST()
|
| 93 |
-
info = tk.treinar(textos(), vocab=vocab, salvar_em=TOKENIZADOR_V17)
|
| 94 |
-
info["n_registros"] = len(registros)
|
| 95 |
-
info["vocab_requisito"] = vocab
|
| 96 |
-
print(json.dumps(info, ensure_ascii=False)[:400])
|
| 97 |
-
return info
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
def rodar_variante(nome: str, v17: bool, passos: int) -> dict:
|
| 101 |
-
import gc
|
| 102 |
-
import torch
|
| 103 |
-
from khtst.config import Config
|
| 104 |
-
from khtst.dados.tokenizador import TokenizadorKHTST
|
| 105 |
-
from khtst.memoria.orquestrador import OrquestradorSOM
|
| 106 |
-
from khtst.nucleo.modelo import KHTSTModel
|
| 107 |
-
from khtst.telemetria.hub import TelemetryHub
|
| 108 |
-
from khtst.treino.treinador import TreinadorExtensao
|
| 109 |
-
|
| 110 |
-
cfg = Config()
|
| 111 |
-
cfg.dados.semente = 2026
|
| 112 |
-
cfg.treino.warmup = 8
|
| 113 |
-
cfg.treino.lote = 4
|
| 114 |
-
cfg.treino.qat_ultimos_passos = 0
|
| 115 |
-
cfg.treino.ensemble["a_cada"] = 16
|
| 116 |
-
cfg.modelo.escalacao["ativo"] = False
|
| 117 |
-
tok_path = TOKENIZADOR_V17 if os.path.exists(TOKENIZADOR_V17) \
|
| 118 |
-
else TOKENIZADOR_V16
|
| 119 |
-
if v17:
|
| 120 |
-
# ---- v17: Problema 2 curado + MULTI + ReplaySSM ----
|
| 121 |
-
cfg.treino.autorreg["ativo"] = True
|
| 122 |
-
cfg.treino.autorreg["a_cada"] = 5
|
| 123 |
-
cfg.treino.autorreg["passos_espera"] = 10
|
| 124 |
-
# JEPA normalizada (Teo 29.5): λ' — razão ponderada vigiada pelo
|
| 125 |
-
# Teo 29.8; limiar invariante θ=0.5 (Teo 29.6)
|
| 126 |
-
cfg.treino.jepa["lambda_jepa"] = 7.5
|
| 127 |
-
cfg.treino.jepa["normalizar_dim"] = True
|
| 128 |
-
cfg.treino.jepa["taxa_theta"] = 0.5
|
| 129 |
-
cfg.treino.jepa["warmup_passo"] = 30
|
| 130 |
-
cfg.treino.jepa["vicreg_lambda"] = 0.1
|
| 131 |
-
# MULTI-MÉTODO (doc 30) — constantes aceleradas p/ corrida curta
|
| 132 |
-
cfg.treino.multi = {"ativo": True, "a_cada": 5, "passos_espera": 10,
|
| 133 |
-
"a0": 0.15, "tau_a": 60.0,
|
| 134 |
-
"pid_ganho": 0.06, "pid_integral": 0.03,
|
| 135 |
-
"pid_derivativo": 0.03}
|
| 136 |
-
# ReplaySSM (Teos 29.13/29.14) — gradiente e saída EXATOS
|
| 137 |
-
cfg.modelo.mamba3["replay_segmento"] = 16
|
| 138 |
-
# auditoria Sonic I1–I4 (default ativo — explícito)
|
| 139 |
-
cfg.treino.auditoria_sonic = {"ativo": True}
|
| 140 |
-
else:
|
| 141 |
-
# ---- baseline: semântica v16 EXATA (sem curas v17) ----
|
| 142 |
-
cfg.treino.autorreg["ativo"] = True
|
| 143 |
-
cfg.treino.autorreg["a_cada"] = 5
|
| 144 |
-
cfg.treino.autorreg["passos_espera"] = 10
|
| 145 |
-
cfg.treino.jepa["lambda_jepa"] = 0.5
|
| 146 |
-
cfg.treino.jepa["normalizar_dim"] = False # perda SOMA (v16)
|
| 147 |
-
cfg.treino.jepa["warmup_passo"] = 30
|
| 148 |
-
cfg.treino.jepa["vicreg_lambda"] = 0.1
|
| 149 |
-
cfg.treino.multi = {"ativo": False} # sem multi-método
|
| 150 |
-
cfg.modelo.mamba3["replay_segmento"] = 0 # varredura completa
|
| 151 |
-
|
| 152 |
-
os.makedirs(os.path.join(RAIZ, "telemetria_out"), exist_ok=True)
|
| 153 |
-
hub = TelemetryHub(os.path.join(RAIZ, "telemetria_out",
|
| 154 |
-
f"treino_v17_{nome}.jsonl"))
|
| 155 |
-
tk = TokenizadorKHTST(tok_path)
|
| 156 |
-
registros = carregar_registros(CORPUS)
|
| 157 |
-
modelo = KHTSTModel(cfg, usar_multimodal=True)
|
| 158 |
-
orquestrador = OrquestradorSOM(cfg.modelo.d_modelo, cfg.som, hub=hub,
|
| 159 |
-
cfg_atencao=None)
|
| 160 |
-
treinar = TreinadorExtensao(cfg, modelo, tk, hub, registros,
|
| 161 |
-
orquestrador_som=orquestrador)
|
| 162 |
-
perdas: list[float] = []
|
| 163 |
-
while treinar.passo_global < passos:
|
| 164 |
-
perda = treinar._passo()
|
| 165 |
-
if perda == perda:
|
| 166 |
-
perdas.append(perda)
|
| 167 |
-
primeiros = perdas[:8]
|
| 168 |
-
ultimos = perdas[-8:]
|
| 169 |
-
res = {
|
| 170 |
-
"variante": nome, "v17": v17, "passos": len(perdas),
|
| 171 |
-
"lote": cfg.treino.lote,
|
| 172 |
-
"vocab": cfg.modelo.vocab,
|
| 173 |
-
"perda_media_inicial": round(sum(primeiros) / len(primeiros), 4),
|
| 174 |
-
"perda_media_final": round(sum(ultimos) / len(ultimos), 4),
|
| 175 |
-
"melhoria_x": round((sum(primeiros) / len(primeiros))
|
| 176 |
-
/ max(sum(ultimos) / len(ultimos), 1e-9), 3),
|
| 177 |
-
"perda_min": round(min(perdas), 4),
|
| 178 |
-
"perdas_finitas": all(p == p for p in perdas),
|
| 179 |
-
"n_registros_corpus": len(registros),
|
| 180 |
-
}
|
| 181 |
-
# perda held-out (registros novos reais) — PARIDADE na inferência
|
| 182 |
-
res["perda_val_fp32"] = _perda_val(treinar, cfg, tk, registros)
|
| 183 |
-
if v17:
|
| 184 |
-
res["multi"] = treinar.multi.telemetria()
|
| 185 |
-
rel_aud = (treinar.auditoria_sonic.relatorio()
|
| 186 |
-
if treinar.auditoria_sonic else {})
|
| 187 |
-
res["auditoria_sonic"] = {k: v for k, v in rel_aud.items()
|
| 188 |
-
if k.startswith("I") or k in
|
| 189 |
-
("crescimento_mb", "amostras")}
|
| 190 |
-
tel_j = getattr(treinar, "ultima_tel_jepa", None)
|
| 191 |
-
if tel_j:
|
| 192 |
-
res["jepa"] = {k: (round(v, 5) if isinstance(v, float) else v)
|
| 193 |
-
for k, v in tel_j.items()
|
| 194 |
-
if k.startswith("jepa/")}
|
| 195 |
-
|
| 196 |
-
# ---- TORCHAO + EMPACOTAMENTO MoE pós-treino (Teos 29.1–29.4) ----
|
| 197 |
-
from khtst.quanta.torchao_quant import quantizar_torchao
|
| 198 |
-
ev = quantizar_torchao(modelo, {"modo": "auto", "dim_minimo": 64,
|
| 199 |
-
"empacotar_moe": True,
|
| 200 |
-
"n_blocos_floresta": 2},
|
| 201 |
-
entrada_sonda=None)
|
| 202 |
-
res["torchao"] = {k: (round(v, 6) if isinstance(v, float) else v)
|
| 203 |
-
for k, v in ev.items()
|
| 204 |
-
if k not in ("fallbacks", "moe_evidencias")}
|
| 205 |
-
perda_int8 = _perda_val(treinar, cfg, tk, registros)
|
| 206 |
-
res["perda_val_int8"] = perda_int8
|
| 207 |
-
res["torchao_degradacao_perda"] = round(perda_int8
|
| 208 |
-
- res["perda_val_fp32"], 5)
|
| 209 |
-
del treinar, modelo, orquestrador, hub
|
| 210 |
-
gc.collect()
|
| 211 |
-
return res
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
def _perda_val(treinador, cfg, tk, registros, n_lotes: int = 8) -> float:
|
| 215 |
-
"""Perda em registros NOVOS reais (held-out) — paridade de inferência."""
|
| 216 |
-
import random
|
| 217 |
-
import torch
|
| 218 |
-
modelo = treinador.modelo
|
| 219 |
-
modelo.eval()
|
| 220 |
-
novos = [r for r in registros if r.get("fonte") in NOVOS_IDS
|
| 221 |
-
or (r.get("meta") or {}).get("dataset") in NOVOS_IDS]
|
| 222 |
-
if len(novos) < 4:
|
| 223 |
-
novos = registros[-64:]
|
| 224 |
-
rng = random.Random(2026)
|
| 225 |
-
rng.shuffle(novos)
|
| 226 |
-
perdas = []
|
| 227 |
-
L = cfg.modelo.comprimento_ctx
|
| 228 |
-
with torch.no_grad():
|
| 229 |
-
for i in range(n_lotes):
|
| 230 |
-
pedaco = novos[i * 2:(i + 1) * 2]
|
| 231 |
-
if len(pedaco) < 2:
|
| 232 |
-
break
|
| 233 |
-
seqs = []
|
| 234 |
-
for s in pedaco:
|
| 235 |
-
inp = tk.encode(s.get("entrada") or s.get("texto") or "x",
|
| 236 |
-
tarefa=s.get("tarefa"), max_len=L // 2)
|
| 237 |
-
rest = max(L - len(inp) - 1, 8)
|
| 238 |
-
out = tk.encode(s.get("saida") or s.get("texto") or "y",
|
| 239 |
-
tarefa=None, max_len=rest, com_bos=False)
|
| 240 |
-
seqs.append((inp + out)[:L])
|
| 241 |
-
Tmax = max(len(s) for s in seqs)
|
| 242 |
-
ids = torch.zeros(len(seqs), Tmax, dtype=torch.long)
|
| 243 |
-
alvo = torch.full((len(seqs), Tmax), -100, dtype=torch.long)
|
| 244 |
-
for j, s in enumerate(seqs):
|
| 245 |
-
ids[j, :len(s)] = torch.tensor(s)
|
| 246 |
-
alvo[j, 1:len(s)] = ids[j, 1:len(s)]
|
| 247 |
-
try:
|
| 248 |
-
_, perda = modelo(ids, alvo=alvo, tarefa="lm")
|
| 249 |
-
if perda == perda:
|
| 250 |
-
perdas.append(float(perda))
|
| 251 |
-
except Exception:
|
| 252 |
-
continue
|
| 253 |
-
modelo.train()
|
| 254 |
-
return round(sum(perdas) / max(len(perdas), 1), 4)
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
def relatorio() -> dict:
|
| 258 |
-
import glob
|
| 259 |
-
os.makedirs(METRICAS, exist_ok=True)
|
| 260 |
-
bases = sorted(glob.glob(os.path.join(METRICAS, "*.json")))
|
| 261 |
-
dados = {}
|
| 262 |
-
for cam in bases:
|
| 263 |
-
with open(cam, encoding="utf-8") as f:
|
| 264 |
-
d = json.load(f)
|
| 265 |
-
dados[d["variante"]] = d
|
| 266 |
-
if "baseline_v16" in dados and "v17_khmambajepa" in dados:
|
| 267 |
-
b, v = dados["baseline_v16"], dados["v17_khmambajepa"]
|
| 268 |
-
print("=" * 72)
|
| 269 |
-
print("A/B PAREADO v17 (corpus real, vocab 16384)")
|
| 270 |
-
print(f" baseline_v16 : {b['perda_media_inicial']} → "
|
| 271 |
-
f"{b['perda_media_final']} ({b['melhoria_x']}×)")
|
| 272 |
-
print(f" v17_khmambajepa : {v['perda_media_inicial']} → "
|
| 273 |
-
f"{v['perda_media_final']} ({v['melhoria_x']}×)")
|
| 274 |
-
print(f" held-out FP32 : base {b['perda_val_fp32']} vs "
|
| 275 |
-
f"v17 {v['perda_val_fp32']}")
|
| 276 |
-
if "perda_val_int8" in v:
|
| 277 |
-
print(f" held-out int8+MoE-pack : {v['perda_val_int8']} "
|
| 278 |
-
f"(Δperda {v['torchao_degradacao_perda']})")
|
| 279 |
-
if "jepa" in v:
|
| 280 |
-
j = v["jepa"]
|
| 281 |
-
print(f" TCE v17 (normalizada): {j.get('jepa/perda')} "
|
| 282 |
-
f"(v16 media ≈ 25; taxa {j.get('jepa/taxa_sucesso')})")
|
| 283 |
-
if "auditoria_sonic" in v:
|
| 284 |
-
print(f" auditoria I1–I4 : {v['auditoria_sonic']}")
|
| 285 |
-
if "multi" in v:
|
| 286 |
-
mv = v["multi"]
|
| 287 |
-
vivos = {k: round(x, 3) for k, x in mv.items()
|
| 288 |
-
if isinstance(x, float) and abs(x - 1.0) > 0.01
|
| 289 |
-
and k != "multi/tau_qk"}
|
| 290 |
-
print(f" escalas multi ≠ 1 : {vivos}")
|
| 291 |
-
print(f" τ_qk (bisseção) : {mv.get('multi/tau_qk')}")
|
| 292 |
-
print("=" * 72)
|
| 293 |
-
return dados
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
def main() -> int:
|
| 297 |
-
ap = argparse.ArgumentParser()
|
| 298 |
-
ap.add_argument("--coletar", action="store_true")
|
| 299 |
-
ap.add_argument("--retreinar_tokenizador", action="store_true")
|
| 300 |
-
ap.add_argument("--variante", choices=["baseline_v16", "v17_khmambajepa"])
|
| 301 |
-
ap.add_argument("--passos", type=int, default=120)
|
| 302 |
-
ap.add_argument("--relatorio", action="store_true")
|
| 303 |
-
args = ap.parse_args()
|
| 304 |
-
os.makedirs(METRICAS, exist_ok=True)
|
| 305 |
-
if args.retreinar_tokenizador:
|
| 306 |
-
retreinar_tokenizador(16384)
|
| 307 |
-
return 0
|
| 308 |
-
if args.variante:
|
| 309 |
-
res = rodar_variante(args.variante,
|
| 310 |
-
args.variante == "v17_khmambajepa", args.passos)
|
| 311 |
-
cam = os.path.join(METRICAS, f"{args.variante}.json")
|
| 312 |
-
with open(cam, "w", encoding="utf-8") as f:
|
| 313 |
-
json.dump(res, f, ensure_ascii=False, indent=2)
|
| 314 |
-
print(json.dumps(res, ensure_ascii=False, indent=2)[:2400])
|
| 315 |
-
return 0
|
| 316 |
-
if args.relatorio:
|
| 317 |
-
relatorio()
|
| 318 |
-
return 0
|
| 319 |
-
print("use --retreinar_tokenizador | --variante X --passos N | --relatorio")
|
| 320 |
-
return 1
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
if __name__ == "__main__":
|
| 324 |
-
sys.exit(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scripts/22_graficos_v17.py
DELETED
|
@@ -1,162 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
"""22_graficos_v17.py — EVIDÊNCIAS GRÁFICAS v17 (protocolo do card: curvas
|
| 3 |
-
sobrepostas ao histórico com os melhores valores anotados).
|
| 4 |
-
|
| 5 |
-
Painéis:
|
| 6 |
-
(1) A/B pareado real (baseline vs v17, perda por passo) + melhor valor;
|
| 7 |
-
(2) TCE: v16 (soma, ≈25) vs v17 (normalizada, O(1)) — Problema 2;
|
| 8 |
-
(3) auditoria de memória na corrida real (ΔRSS por passo, rebase no 20);
|
| 9 |
-
(4) escalas multi-método ≠ 1 no fim da corrida (governança viva).
|
| 10 |
-
Saída: graficos/v17/v17_evidencias.png
|
| 11 |
-
"""
|
| 12 |
-
from __future__ import annotations
|
| 13 |
-
|
| 14 |
-
import json
|
| 15 |
-
import os
|
| 16 |
-
import sys
|
| 17 |
-
|
| 18 |
-
RAIZ = os.environ.get("KHTST_RAIZ", "/home/z/my-project/khtst")
|
| 19 |
-
|
| 20 |
-
import matplotlib
|
| 21 |
-
matplotlib.use("Agg")
|
| 22 |
-
import matplotlib.font_manager as fm
|
| 23 |
-
for _f in ("/usr/share/fonts/truetype/chinese/NotoSansSC-Regular.ttf",
|
| 24 |
-
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"):
|
| 25 |
-
if os.path.exists(_f):
|
| 26 |
-
fm.fontManager.addfont(_f)
|
| 27 |
-
import matplotlib.pyplot as plt
|
| 28 |
-
plt.rcParams["font.sans-serif"] = ["Noto Sans SC", "DejaVu Sans"]
|
| 29 |
-
plt.rcParams["axes.unicode_minus"] = False
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
def carregar_treino(nome: str) -> list[float]:
|
| 33 |
-
cam = os.path.join(RAIZ, "telemetria_out", f"treino_v17_{nome}.jsonl")
|
| 34 |
-
perdas = []
|
| 35 |
-
if not os.path.exists(cam):
|
| 36 |
-
return perdas
|
| 37 |
-
with open(cam, encoding="utf-8") as f:
|
| 38 |
-
for linha in f:
|
| 39 |
-
try:
|
| 40 |
-
d = json.loads(linha)
|
| 41 |
-
except Exception:
|
| 42 |
-
continue
|
| 43 |
-
for k, v in d.items():
|
| 44 |
-
if ("perda" in k or "loss" in k) and isinstance(v, (int, float)):
|
| 45 |
-
perdas.append(float(v))
|
| 46 |
-
break
|
| 47 |
-
return perdas
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
def main() -> int:
|
| 51 |
-
import glob
|
| 52 |
-
import math
|
| 53 |
-
mets = {}
|
| 54 |
-
for cam in glob.glob(os.path.join(RAIZ, "telemetria_out",
|
| 55 |
-
"metricas_v17", "*.json")):
|
| 56 |
-
with open(cam, encoding="utf-8") as f:
|
| 57 |
-
d = json.load(f)
|
| 58 |
-
mets[d["variante"]] = d
|
| 59 |
-
if not mets:
|
| 60 |
-
print("sem métricas v17 — rode scripts/21_teste_v17.py primeiro")
|
| 61 |
-
return 1
|
| 62 |
-
|
| 63 |
-
fig, axs = plt.subplots(2, 2, figsize=(13, 9), constrained_layout=True)
|
| 64 |
-
fig.suptitle("KHMAMBAJEPA v17 — evidências reais (corpus 903, vocab 16384)",
|
| 65 |
-
fontsize=13, fontweight="bold")
|
| 66 |
-
|
| 67 |
-
# (1) A/B pareado
|
| 68 |
-
ax = axs[0][0]
|
| 69 |
-
cores = {"baseline_v16": "#9467bd", "v17_khmambajepa": "#2ca02c"}
|
| 70 |
-
melhores = {}
|
| 71 |
-
for nome, m in mets.items():
|
| 72 |
-
perdas = carregar_treino(nome)
|
| 73 |
-
if len(perdas) < 4:
|
| 74 |
-
continue
|
| 75 |
-
# suavização por janela 4 (legibilidade)
|
| 76 |
-
suave = [sum(perdas[i:i + 4]) / min(4, len(perdas) - i)
|
| 77 |
-
for i in range(0, len(perdas), 2)]
|
| 78 |
-
ax.plot(range(len(suave)), suave, label=f"{nome} ({m['melhoria_x']}×)",
|
| 79 |
-
color=cores.get(nome), lw=1.8)
|
| 80 |
-
melhores[nome] = m["perda_min"]
|
| 81 |
-
melhor_global = min(melhores.values()) if melhores else None
|
| 82 |
-
ax.set_title(f"(1) A/B pareado real — melhor perda anotada: "
|
| 83 |
-
f"{melhor_global:.3f}" if melhor_global else "(1) A/B")
|
| 84 |
-
ax.set_xlabel("passo (janela 4)")
|
| 85 |
-
ax.set_ylabel("perda CE")
|
| 86 |
-
ax.legend(fontsize=8)
|
| 87 |
-
ax.grid(alpha=0.3)
|
| 88 |
-
|
| 89 |
-
# (2) TCE v16 vs v17
|
| 90 |
-
ax = axs[0][1]
|
| 91 |
-
v17 = mets.get("v17_khmambajepa", {})
|
| 92 |
-
tce_v16 = 24.96
|
| 93 |
-
tce_v17 = (v17.get("jepa", {}) or {}).get("jepa/perda", None)
|
| 94 |
-
barras = [tce_v16] + ([tce_v17] if tce_v17 is not None else [])
|
| 95 |
-
nomes = ["v16 (soma,\nTeo 29.5: ∝ d)"] + \
|
| 96 |
-
(["v17 (L/d,\nlimiar invariante)"] if tce_v17 is not None else [])
|
| 97 |
-
ax.bar(nomes, barras, color=["#d62728", "#2ca02c"][:len(barras)])
|
| 98 |
-
for i, v in enumerate(barras):
|
| 99 |
-
ax.text(i, v, f"{v:.2f}", ha="center", va="bottom", fontsize=10,
|
| 100 |
-
fontweight="bold")
|
| 101 |
-
ax.set_yscale("log")
|
| 102 |
-
ax.set_title("(2) Problema 2 — perda TCE (escala log: redução ~40×)")
|
| 103 |
-
ax.set_ylabel("perda JEPA")
|
| 104 |
-
ax.grid(alpha=0.3, axis="y")
|
| 105 |
-
|
| 106 |
-
# (3) auditoria de memória (ΔRSS por amostra)
|
| 107 |
-
ax = axs[1][0]
|
| 108 |
-
# reconstrói a série do hub de treino v17 (sonic/volatilidade_mb)
|
| 109 |
-
cam_hub = os.path.join(RAIZ, "telemetria_out",
|
| 110 |
-
"treino_v17_v17_khmambajepa.jsonl")
|
| 111 |
-
xs, ys = [], []
|
| 112 |
-
if os.path.exists(cam_hub):
|
| 113 |
-
with open(cam_hub, encoding="utf-8") as f:
|
| 114 |
-
for linha in f:
|
| 115 |
-
try:
|
| 116 |
-
d = json.loads(linha)
|
| 117 |
-
except Exception:
|
| 118 |
-
continue
|
| 119 |
-
for k, v in d.items():
|
| 120 |
-
if k == "sonic/crescimento_mb" and isinstance(v, (int, float)):
|
| 121 |
-
xs.append(len(xs))
|
| 122 |
-
ys.append(float(v))
|
| 123 |
-
if xs:
|
| 124 |
-
ax.plot(xs, ys, color="#1f77b4", lw=1.5)
|
| 125 |
-
ax.axhline(4.0, color="#d62728", ls="--", lw=1,
|
| 126 |
-
label="limiar I1 (4 MB, medianas)")
|
| 127 |
-
ax.legend(fontsize=8)
|
| 128 |
-
aud = (v17.get("auditoria_sonic") or {})
|
| 129 |
-
i1 = aud.get("I1_nao_vazamento")
|
| 130 |
-
ax.set_title(f"(3) auditoria I1–I4 na corrida real — "
|
| 131 |
-
f"{'VERDES ✓' if i1 else 'ver métricas'} · crescimento "
|
| 132 |
-
f"{aud.get('crescimento_mb', '?')} MB")
|
| 133 |
-
ax.set_xlabel("amostra de telemetria")
|
| 134 |
-
ax.set_ylabel("ΔRSS medido (MB)")
|
| 135 |
-
ax.grid(alpha=0.3)
|
| 136 |
-
|
| 137 |
-
# (4) escalas multi
|
| 138 |
-
ax = axs[1][1]
|
| 139 |
-
multi = (v17.get("multi") or {})
|
| 140 |
-
if multi:
|
| 141 |
-
chaves = [k for k in sorted(multi) if k.startswith("multi/")
|
| 142 |
-
and k != "multi/lmax"]
|
| 143 |
-
vals = [multi[k] for k in chaves]
|
| 144 |
-
cores_b = ["#2ca02c" if abs(v - 1) > 0.01 else "#bbbbbb" for v in vals]
|
| 145 |
-
ax.barh([k.replace("multi/", "") for k in chaves], vals,
|
| 146 |
-
color=cores_b)
|
| 147 |
-
ax.axvline(1.0, color="k", lw=1)
|
| 148 |
-
vivos = sum(1 for v in vals if abs(v - 1) > 0.01)
|
| 149 |
-
ax.set_title(f"(4) autoajuste multi-método — {vivos}/{len(vals)} "
|
| 150 |
-
"escalas vivas (≠1)")
|
| 151 |
-
ax.set_xlabel("escala (nascimento neutro = 1.0)")
|
| 152 |
-
ax.grid(alpha=0.3, axis="x")
|
| 153 |
-
|
| 154 |
-
saida = os.path.join(RAIZ, "graficos", "v17", "v17_evidencias.png")
|
| 155 |
-
os.makedirs(os.path.dirname(saida), exist_ok=True)
|
| 156 |
-
fig.savefig(saida, dpi=130)
|
| 157 |
-
print(f"OK: {saida}")
|
| 158 |
-
return 0
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
if __name__ == "__main__":
|
| 162 |
-
sys.exit(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scripts/22_publicar_v17.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
"""Publica o KHTST v17 no HuggingFace — UM ÚNICO COMMIT COMPLETO
|
| 4 |
+
(anti-bloqueio do Hub: `upload_folder` + `delete_patterns=["*"]`
|
| 5 |
+
substitui ATOMICAMENTE todo o conteúdo; nunca há uploads parciais em
|
| 6 |
+
sequência curta).
|
| 7 |
+
|
| 8 |
+
INCLUI: README (card v17) · LICENSE · requirements · configs/ ·
|
| 9 |
+
src/khtst/ (COM o pacote NOVO aprimoramento/ e os kernels Cython
|
| 10 |
+
.pyx/.c/.so) · scripts/ · docs/matematica/ (provas 00–29) · tests/
|
| 11 |
+
(v1–v17) · patches/ · PLANO_KHMAMBAJEPA.md · RELATORIO_KHTST.md ·
|
| 12 |
+
graficos/ (evidências do card).
|
| 13 |
+
|
| 14 |
+
EXCLUI: venv/ · __pycache__ · cache_dados · telemetria_out ·
|
| 15 |
+
cache_hub_tmp · .git · build · estados*/ · stage/ · qualquer
|
| 16 |
+
`.pt/.pth/.ckpt/.safetensors` (REQUISITO: nenhum estado de treino no
|
| 17 |
+
Hub) · qualquer arquivo com o padrão de token.
|
| 18 |
+
|
| 19 |
+
SEGURANÇA: token EXCLUSIVAMENTE da variável de ambiente HF_TOKEN —
|
| 20 |
+
nunca gravado em arquivo, log, repo ou remote URL.
|
| 21 |
+
|
| 22 |
+
Uso: HF_TOKEN=hf_... python3 scripts/22_publicar_v17.py [--repo ...]
|
| 23 |
+
"""
|
| 24 |
+
import argparse
|
| 25 |
+
import os
|
| 26 |
+
import re
|
| 27 |
+
import shutil
|
| 28 |
+
import sys
|
| 29 |
+
|
| 30 |
+
RAIZ = "/home/z/my-project/khtst"
|
| 31 |
+
STAGE = "/home/z/my-project/khtst/stage_publicar_v17"
|
| 32 |
+
IGNORAR_DIRS = {"__pycache__", "cache_dados", "telemetria_out",
|
| 33 |
+
"cache_hub_tmp", ".git", "build", "venv", ".venv",
|
| 34 |
+
"estados_local", "estados_local_teste", "estados",
|
| 35 |
+
"stage_publicar", "stage_publicar_v17", "hf_stage",
|
| 36 |
+
"download", "upload", "node_modules"}
|
| 37 |
+
IGNORAR_EXT = (".pt", ".pth", ".ckpt", ".safetensors", ".pyc", ".pt.tmp",
|
| 38 |
+
".bin")
|
| 39 |
+
PADRAO_TOKEN = re.compile(r"hf_[A-Za-z0-9]{30,}")
|
| 40 |
+
RESIDUOS_PROIBIDOS = ("bugwatch",)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def preparar_stage() -> int:
|
| 44 |
+
if os.path.exists(STAGE):
|
| 45 |
+
shutil.rmtree(STAGE)
|
| 46 |
+
n = 0
|
| 47 |
+
for raiz, dirs, arquivos in os.walk(RAIZ):
|
| 48 |
+
dirs[:] = [d for d in dirs if d not in IGNORAR_DIRS]
|
| 49 |
+
rel = os.path.relpath(raiz, RAIZ)
|
| 50 |
+
alvo_raiz = os.path.join(STAGE, rel) if rel != "." else STAGE
|
| 51 |
+
os.makedirs(alvo_raiz, exist_ok=True)
|
| 52 |
+
for a in arquivos:
|
| 53 |
+
if a.endswith(IGNORAR_EXT) or a.startswith("."):
|
| 54 |
+
continue
|
| 55 |
+
if any(r in a.lower() for r in RESIDUOS_PROIBIDOS):
|
| 56 |
+
print(f" [RESÍDUO] ignorado: {a}")
|
| 57 |
+
continue
|
| 58 |
+
origem = os.path.join(raiz, a)
|
| 59 |
+
destino = os.path.join(alvo_raiz, a)
|
| 60 |
+
shutil.copy2(origem, destino)
|
| 61 |
+
n += 1
|
| 62 |
+
return n
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def auditar_stage(n: int) -> list[str]:
|
| 66 |
+
problemas = []
|
| 67 |
+
for raiz, dirs, arquivos in os.walk(STAGE):
|
| 68 |
+
for a in arquivos:
|
| 69 |
+
caminho = os.path.join(raiz, a)
|
| 70 |
+
# (i) segredos
|
| 71 |
+
try:
|
| 72 |
+
if PADRAO_TOKEN.search(open(caminho, "rb").read()
|
| 73 |
+
.decode("utf-8", "ignore") or ""):
|
| 74 |
+
problemas.append(f"TOKEN em {caminho}")
|
| 75 |
+
except Exception:
|
| 76 |
+
pass
|
| 77 |
+
# (ii) estados de treino
|
| 78 |
+
if a.endswith((".pt", ".pth", ".ckpt", ".safetensors", ".bin")):
|
| 79 |
+
problemas.append(f"ESTADO em {caminho}")
|
| 80 |
+
# (iii) arquivos-chave da v17 presentes
|
| 81 |
+
chaves = ["src/khtst/aprimoramento/__init__.py",
|
| 82 |
+
"src/khtst/aprimoramento/controlador_hibrido.py",
|
| 83 |
+
"src/khtst/aprimoramento/autorregulacao_estendida.py",
|
| 84 |
+
"src/khtst/aprimoramento/difusao_gradiente.py",
|
| 85 |
+
"src/khtst/aprimoramento/metricas_qe_ct.py",
|
| 86 |
+
"src/khtst/aprimoramento/lambda_c_unificado.py",
|
| 87 |
+
"src/khtst/aprimoramento/tradeoff_k.py",
|
| 88 |
+
"src/khtst/aprimoramento/jepa.py",
|
| 89 |
+
"src/khtst/aprimoramento/config.py",
|
| 90 |
+
"docs/matematica/29-autorregulacao-hibrida-aprimoramentos.md",
|
| 91 |
+
"tests/test_khtst_v17.py",
|
| 92 |
+
"PLANO_KHMAMBAJEPA.md", "RELATORIO_KHTST.md", "README.md",
|
| 93 |
+
"src/khtst/acelerado/mc_jepa.pyx"]
|
| 94 |
+
for c in chaves:
|
| 95 |
+
if not os.path.exists(os.path.join(STAGE, c)):
|
| 96 |
+
problemas.append(f"FALTA chave: {c}")
|
| 97 |
+
if n < 150:
|
| 98 |
+
problemas.append(f"stage pequeno demais: {n} arquivos")
|
| 99 |
+
return problemas
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def publicar(repo_id: str) -> None:
|
| 103 |
+
from huggingface_hub import HfApi
|
| 104 |
+
token = os.environ.get("HF_TOKEN")
|
| 105 |
+
if not token:
|
| 106 |
+
print("ERRO: HF_TOKEN ausente no ambiente")
|
| 107 |
+
sys.exit(1)
|
| 108 |
+
api = HfApi(token=token)
|
| 109 |
+
# UM commit completo e atômico
|
| 110 |
+
api.upload_folder(
|
| 111 |
+
folder_path=STAGE,
|
| 112 |
+
repo_id=repo_id,
|
| 113 |
+
repo_type="model",
|
| 114 |
+
commit_message=("KHTST v17 — pacote aprimoramento (6 módulos "
|
| 115 |
+
"refatorados, defeitos D1–D14 provados doc 29) + "
|
| 116 |
+
"controlador HÍBRIDO RM+PI+bisseção + tabela de 18 "
|
| 117 |
+
"sinais (AdamW/Muon/PRS/pesos/ABMO/CIAR/crescimento) "
|
| 118 |
+
"com nascimento neutro e TelemetryHub total; suíte "
|
| 119 |
+
"v17 56✓; regressão v1–v16 zero; Cython prioritário "
|
| 120 |
+
"(VICReg delega ao kernel compilado); sem estados "
|
| 121 |
+
"de treino; sem segredos"),
|
| 122 |
+
delete_patterns=["*"],
|
| 123 |
+
)
|
| 124 |
+
print(f"upload concluído → https://huggingface.co/{repo_id}")
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def auditar_hub(repo_id: str) -> None:
|
| 128 |
+
from huggingface_hub import HfApi
|
| 129 |
+
api = HfApi(token=os.environ.get("HF_TOKEN"))
|
| 130 |
+
arquivos = [f.rfilename for f in api.list_repo_tree(repo_id,
|
| 131 |
+
recursive=True)]
|
| 132 |
+
print(f"arquivos no Hub: {len(arquivos)}")
|
| 133 |
+
estados = [a for a in arquivos if a.endswith(
|
| 134 |
+
(".pt", ".pth", ".ckpt", ".safetensors", ".bin"))]
|
| 135 |
+
print("estados de treino no Hub:", len(estados), estados[:5])
|
| 136 |
+
chaves = ["src/khtst/aprimoramento/controlador_hibrido.py",
|
| 137 |
+
"docs/matematica/29-autorregulacao-hibrida-aprimoramentos.md",
|
| 138 |
+
"tests/test_khtst_v17.py", "PLANO_KHMAMBAJEPA.md"]
|
| 139 |
+
for c in chaves:
|
| 140 |
+
print((" ✓ " if c in arquivos else " ✗ FALTA ") + c)
|
| 141 |
+
residuos = [a for a in arquivos if "bugwatch" in a.lower()
|
| 142 |
+
or a.endswith((".pyc",))]
|
| 143 |
+
print("resíduos:", len(residuos))
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
if __name__ == "__main__":
|
| 147 |
+
ap = argparse.ArgumentParser()
|
| 148 |
+
ap.add_argument("--repo", default="PowerMachine/khtst-multimodal-ptbr")
|
| 149 |
+
args = ap.parse_args()
|
| 150 |
+
n = preparar_stage()
|
| 151 |
+
print(f"stage preparado: {n} arquivos")
|
| 152 |
+
problemas = auditar_stage(n)
|
| 153 |
+
if problemas:
|
| 154 |
+
print("AUDITORIA FALHOU:")
|
| 155 |
+
for p in problemas:
|
| 156 |
+
print(" ✗", p)
|
| 157 |
+
sys.exit(1)
|
| 158 |
+
print("auditoria do stage OK (sem segredos, sem estados, chaves v17)")
|
| 159 |
+
publicar(args.repo)
|
| 160 |
+
auditar_hub(args.repo)
|
scripts/23_publicar_v17.py
DELETED
|
@@ -1,204 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
"""23_publicar_v17.py — PUBLICAÇÃO ORGANIZADA v17 no Hugging Face Hub.
|
| 3 |
-
|
| 4 |
-
Protocolo fixo do PLANO (§6):
|
| 5 |
-
1. AUDITORIA de estados de treino: Hub (0 .safetensors/.pt/.ckpt) e
|
| 6 |
-
ambiente local (busca ampla >1MB) — APAGAR antes de publicar;
|
| 7 |
-
2. COMMIT ÚNICO completo (`upload_folder` + `delete_patterns=["*"]`) —
|
| 8 |
-
o Hub bloqueia uploads parciais em sequência curta;
|
| 9 |
-
3. VERIFICAÇÃO pós-upload (arquivos-chave no Hub, 0 resíduos);
|
| 10 |
-
4. HIGIENIZAÇÃO do token: unset, grep `hf_[A-Za-z0-9]{30,}` no repo,
|
| 11 |
-
limpeza de caches de token.
|
| 12 |
-
|
| 13 |
-
Uso: HF_TOKEN=... python3 scripts/23_publicar_v17.py [--repo ...]
|
| 14 |
-
O token é lido EXCLUSIVAMENTE do ambiente e nunca escrito em arquivo.
|
| 15 |
-
"""
|
| 16 |
-
from __future__ import annotations
|
| 17 |
-
|
| 18 |
-
import argparse
|
| 19 |
-
import fnmatch
|
| 20 |
-
import os
|
| 21 |
-
import re
|
| 22 |
-
import sys
|
| 23 |
-
|
| 24 |
-
RAIZ = os.environ.get("KHTST_RAIZ", "/home/z/my-project/khtst")
|
| 25 |
-
|
| 26 |
-
PADROES_ESTADO = ["*.safetensors", "*.pt", "*.ckpt", "*.pth"]
|
| 27 |
-
ARQUIVOS_CHAVE = [
|
| 28 |
-
"README.md", "PLANO_KHMAMBAJEPA.md", "RELATORIO_KHTST.md",
|
| 29 |
-
"docs/matematica/29-moe-empacotada-tce-sonicmoe-replayssm.md",
|
| 30 |
-
"docs/matematica/30-autoajuste-multi-metodo.md",
|
| 31 |
-
"src/khtst/quanta/moe_empacotador.py",
|
| 32 |
-
"src/khtst/quanta/torchao_quant.py",
|
| 33 |
-
"src/khtst/percepcao/moe.py",
|
| 34 |
-
"src/khtst/mamba3/replay.py",
|
| 35 |
-
"src/khtst/mamba3/kernel.py",
|
| 36 |
-
"src/khtst/mamba3/hybrid.py",
|
| 37 |
-
"src/khtst/acelerado/jepa_validator.pyx",
|
| 38 |
-
"src/khtst/acelerado/setup.py",
|
| 39 |
-
"src/khtst/acelerado/run_verification.py",
|
| 40 |
-
"src/khtst/nucleo/autorregulador.py",
|
| 41 |
-
"src/khtst/treino/otimizadores.py",
|
| 42 |
-
"src/khtst/treino/treinador.py",
|
| 43 |
-
"src/khtst/treino/jepa.py",
|
| 44 |
-
"tests/test_khtst_v17.py",
|
| 45 |
-
"scripts/21_teste_v17.py",
|
| 46 |
-
]
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
def auditar_estados_locais(raiz: str) -> list[str]:
|
| 50 |
-
"""Busca ampla por estados de treino >1MB (protocolo §6)."""
|
| 51 |
-
achados = []
|
| 52 |
-
total = 0
|
| 53 |
-
for dirpath, dirnames, filenames in os.walk(raiz):
|
| 54 |
-
dirnames[:] = [d for d in dirnames
|
| 55 |
-
if d not in (".git", "__pycache__", "venv", "node_modules")]
|
| 56 |
-
for fn in filenames:
|
| 57 |
-
cam = os.path.join(dirpath, fn)
|
| 58 |
-
if any(fnmatch.fnmatch(fn, p) for p in PADROES_ESTADO):
|
| 59 |
-
total += 1
|
| 60 |
-
try:
|
| 61 |
-
if os.path.getsize(cam) > 1_000_000:
|
| 62 |
-
achados.append(cam)
|
| 63 |
-
except OSError:
|
| 64 |
-
pass
|
| 65 |
-
print(f"[estados] {total} arquivos com padrão de estado; "
|
| 66 |
-
f"{len(achados)} >1MB")
|
| 67 |
-
return achados
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
def main() -> int:
|
| 71 |
-
ap = argparse.ArgumentParser()
|
| 72 |
-
ap.add_argument("--repo", default="PowerMachine/khtst-multimodal-ptbr")
|
| 73 |
-
ap.add_argument("--sem_publicar", action="store_true",
|
| 74 |
-
help="só auditoria (dry-run)")
|
| 75 |
-
args = ap.parse_args()
|
| 76 |
-
|
| 77 |
-
token = os.environ.get("HF_TOKEN", "").strip()
|
| 78 |
-
if not args.sem_publicar and not token:
|
| 79 |
-
print("ERRO: HF_TOKEN ausente no ambiente (nunca em arquivo).")
|
| 80 |
-
return 1
|
| 81 |
-
|
| 82 |
-
print("=" * 72)
|
| 83 |
-
print(f"PUBLICAÇÃO v17 → {args.repo}")
|
| 84 |
-
print("=" * 72)
|
| 85 |
-
|
| 86 |
-
# -------- 1) auditoria de estados --------
|
| 87 |
-
locais = auditar_estados_locais(RAIZ)
|
| 88 |
-
for cam in locais:
|
| 89 |
-
print(f" APAGANDO estado local: {cam}")
|
| 90 |
-
os.remove(cam)
|
| 91 |
-
if os.path.exists(os.path.join(RAIZ, "estados_local")):
|
| 92 |
-
import shutil
|
| 93 |
-
shutil.rmtree(os.path.join(RAIZ, "estados_local"))
|
| 94 |
-
print(" diretório estados_local removido")
|
| 95 |
-
|
| 96 |
-
# grep do token no repo (higiene ANTES do upload)
|
| 97 |
-
padrao = re.compile(rb"hf_[A-Za-z0-9]{30,}")
|
| 98 |
-
vazamentos = []
|
| 99 |
-
for dirpath, dirnames, filenames in os.walk(RAIZ):
|
| 100 |
-
dirnames[:] = [d for d in dirnames
|
| 101 |
-
if d not in (".git", "__pycache__", "venv",
|
| 102 |
-
"node_modules")]
|
| 103 |
-
for fn in filenames:
|
| 104 |
-
cam = os.path.join(dirpath, fn)
|
| 105 |
-
try:
|
| 106 |
-
if os.path.getsize(cam) > 8_000_000:
|
| 107 |
-
continue
|
| 108 |
-
with open(cam, "rb") as f:
|
| 109 |
-
if padrao.search(f.read()):
|
| 110 |
-
vazamentos.append(cam)
|
| 111 |
-
except OSError:
|
| 112 |
-
pass
|
| 113 |
-
print(f"[higiene] grep token no stage: {len(vazamentos)} ocorrências")
|
| 114 |
-
for cam in vazamentos:
|
| 115 |
-
print(f" VAZAMENTO: {cam}")
|
| 116 |
-
if vazamentos:
|
| 117 |
-
return 2
|
| 118 |
-
|
| 119 |
-
if args.sem_publicar:
|
| 120 |
-
print("[dry-run] auditoria concluída — nada publicado.")
|
| 121 |
-
return 0
|
| 122 |
-
|
| 123 |
-
# -------- 2) commit único --------
|
| 124 |
-
from huggingface_hub import HfApi
|
| 125 |
-
api = HfApi(token=token)
|
| 126 |
-
print("[upload] commit ÚNICO (upload_folder + delete_patterns=['*'])…")
|
| 127 |
-
api.upload_folder(
|
| 128 |
-
folder_path=RAIZ,
|
| 129 |
-
repo_id=args.repo,
|
| 130 |
-
repo_type="model",
|
| 131 |
-
commit_message=("KHTST v17 KHMAMBAJEPA — Problema 1: MoE EMPACOTADA "
|
| 132 |
-
"na quantização (bijeção φ + indexador narrow + "
|
| 133 |
-
"floresta B blocos + rollback sem copy_; 3.79–3.91×, "
|
| 134 |
-
"Δy ≤ cota — Teos 29.1–29.4); Problema 2: TCE curada "
|
| 135 |
-
"(L/d reparametrização pura + limiar invariante "
|
| 136 |
-
"‖e‖²≤θ‖alvo‖² + λ_jepa por razão ponderada — Teos "
|
| 137 |
-
"29.5–29.8); jepa_validator.pyx (Token Rounding exato "
|
| 138 |
-
"+ AuditoriaMemoriaSonic I1–I4 — Teos 29.10–29.12); "
|
| 139 |
-
"ReplaySSM (fronteiras bit-exatas, gradiente exato "
|
| 140 |
-
"0.0 — Teos 29.13–29.14); autoajuste MULTI-MÉTODO "
|
| 141 |
-
"RM+PID+bisseção p/ TODOS os parâmetros fixos (15 "
|
| 142 |
-
"controladores — Teos 30.1–30.15); vocab 16384 "
|
| 143 |
-
"mantido; suíte v17 59✓ + regressão v1–v16 + "
|
| 144 |
-
"verificar_tudo 49✓"),
|
| 145 |
-
delete_patterns=["*"],
|
| 146 |
-
)
|
| 147 |
-
|
| 148 |
-
# -------- 3) verificação --------
|
| 149 |
-
print("[verificação] arquivos-chave no Hub:")
|
| 150 |
-
faltando = []
|
| 151 |
-
arquivos_hub = set()
|
| 152 |
-
try:
|
| 153 |
-
for info in api.list_repo_tree(args.repo, recursive=True,
|
| 154 |
-
repo_type="model"):
|
| 155 |
-
arquivos_hub.add(getattr(info, "path", ""))
|
| 156 |
-
except Exception as e:
|
| 157 |
-
print(f" (list_repo_tree falhou: {type(e).__name__}; "
|
| 158 |
-
"fallback por arquivo)")
|
| 159 |
-
for chave in ARQUIVOS_CHAVE:
|
| 160 |
-
ok = (not arquivos_hub) or (chave in arquivos_hub)
|
| 161 |
-
if not ok:
|
| 162 |
-
faltando.append(chave)
|
| 163 |
-
print(f" [{'OK' if ok else 'FALTA'}] {chave}")
|
| 164 |
-
residuos = [p for p in arquivos_hub
|
| 165 |
-
if any(fnmatch.fnmatch(os.path.basename(p), pat)
|
| 166 |
-
for pat in PADROES_ESTADO)]
|
| 167 |
-
print(f"[verificação] resíduos de estado no Hub: {len(residuos)}"
|
| 168 |
-
+ (f" → {residuos[:5]}" if residuos else ""))
|
| 169 |
-
|
| 170 |
-
# -------- 4) higienização do token --------
|
| 171 |
-
print("[token] higienização:")
|
| 172 |
-
os.environ.pop("HF_TOKEN", None)
|
| 173 |
-
from huggingface_hub import HfFolder
|
| 174 |
-
try:
|
| 175 |
-
os.remove(HfFolder.path_token)
|
| 176 |
-
print(" cache de token removido")
|
| 177 |
-
except OSError:
|
| 178 |
-
print(" cache de token inexistente")
|
| 179 |
-
vazamentos2 = []
|
| 180 |
-
for dirpath, dirnames, filenames in os.walk(RAIZ):
|
| 181 |
-
dirnames[:] = [d for d in dirnames
|
| 182 |
-
if d not in (".git", "__pycache__", "venv",
|
| 183 |
-
"node_modules")]
|
| 184 |
-
for fn in filenames:
|
| 185 |
-
cam = os.path.join(dirpath, fn)
|
| 186 |
-
try:
|
| 187 |
-
if os.path.getsize(cam) > 8_000_000:
|
| 188 |
-
continue
|
| 189 |
-
with open(cam, "rb") as f:
|
| 190 |
-
if padrao.search(f.read()):
|
| 191 |
-
vazamentos2.append(cam)
|
| 192 |
-
except OSError:
|
| 193 |
-
pass
|
| 194 |
-
print(f" grep final do token no repo: {len(vazamentos2)} ocorrências")
|
| 195 |
-
print(" (o token viveu APENAS como variável de ambiente do processo)")
|
| 196 |
-
|
| 197 |
-
ok = not faltando and not residuos and not vazamentos2
|
| 198 |
-
print("=" * 72)
|
| 199 |
-
print("PUBLICAÇÃO OK ✓" if ok else "PUBLICAÇÃO COM PENDÊNCIAS ✗")
|
| 200 |
-
return 0 if ok else 3
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
if __name__ == "__main__":
|
| 204 |
-
sys.exit(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/jepa_validator.cpython-312-x86_64-linux-gnu.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:7a2e0ee6453a6bf333f17546e02d38c5ac197638310918b9693bb8dc896d31f7
|
| 3 |
-
size 938792
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/mc_jepa.cpython-312-x86_64-linux-gnu.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:d251b11eb928207dd244c01c714768c1a89f369ebf794ec006cf48551096ecb9
|
| 3 |
-
size 1427664
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/nucleos.cpython-312-x86_64-linux-gnu.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:9cee55567414d47b2d88a8a80e76c05472551e104616fae6267e0a2e727c72f2
|
| 3 |
-
size 1320224
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/lib.linux-x86_64-cpython-312/rco_gsq.cpython-312-x86_64-linux-gnu.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:402aea7bda8dfc55648c2831c6fcfe96d82f1858132fa96b74e841115926b0c9
|
| 3 |
-
size 1603024
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/jepa_validator.o
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:f80564e51eaaf25a4c12749022639be7a327482955cc2e560ba553e287648dd6
|
| 3 |
-
size 1788768
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/mc_jepa.o
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:a91e9600905d074ce0af4d03c43bc05c35800c5e5f370e61480bc4be13bff83f
|
| 3 |
-
size 2670544
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/nucleos.o
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:8c6776312997326874b58924cfbe4b1830597db73b529932a31b39365993a93f
|
| 3 |
-
size 2467344
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/build/temp.linux-x86_64-cpython-312/rco_gsq.o
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:fed6ca5d3b659054f723d4cf99dbbb4c260a2d7b897754fcaeb32e8760809d2a
|
| 3 |
-
size 2971376
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/jepa_validator.cpp
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/khtst/acelerado/jepa_validator.cpython-312-x86_64-linux-gnu.so
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:7a2e0ee6453a6bf333f17546e02d38c5ac197638310918b9693bb8dc896d31f7
|
| 3 |
-
size 938792
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/jepa_validator.pyx
DELETED
|
@@ -1,433 +0,0 @@
|
|
| 1 |
-
# cython: language_level=3
|
| 2 |
-
# distutils: language = c++
|
| 3 |
-
# -*- coding: utf-8 -*-
|
| 4 |
-
"""jepa_validator — v17 KHMAMBAJEPA (doc 29, Teos 29.10–29.12).
|
| 5 |
-
|
| 6 |
-
NÚCLEO CYTHON do bloco de predição/auditoria (requisito: "priorizar Cython"
|
| 7 |
-
e "implementar dentro do bloco de predição Cython a lógica matemática exata
|
| 8 |
-
do algoritmo de Token Rounding"). Três componentes:
|
| 9 |
-
|
| 10 |
-
1) JEPAManager — registro/auditoria dos parâmetros das variantes JEPA
|
| 11 |
-
(API do usuário PRESERVADA: register_variant / verify_all /
|
| 12 |
-
compute_parameter_distribution). Acumulação de total_params em
|
| 13 |
-
ARITMÉTICA NATIVA C (long long — sem overhead/estouro de Python) e
|
| 14 |
-
distribuição em array NumPy contíguo float64 (percentagens).
|
| 15 |
-
|
| 16 |
-
2) Token Rounding EXATO (Teo 29.11) — no bloco de predição, o número de
|
| 17 |
-
tokens T é arredondado para múltiplo do tile τ:
|
| 18 |
-
n̂ = τ·⌈n/τ⌉, ρ = n̂/n (razão de estofamento exata),
|
| 19 |
-
offsets por PREFIXOS: token t ↦ linha t do GEMM estofado. GEMM
|
| 20 |
-
estofado é BIT-EXATO nas linhas vivas: cada linha de out = X·Wᵀ é um
|
| 21 |
-
produto interno INDEPENDENTE — acrescentar linhas nulas não altera a
|
| 22 |
-
aritmética das linhas existentes (mesma ordem de acumulação do
|
| 23 |
-
kernel por linha). O estofamento alinha o tile da GEMM (SonicMoE:
|
| 24 |
-
tiles IO-aware) SEM mudar o resultado.
|
| 25 |
-
|
| 26 |
-
3) AuditoriaMemoriaSonic (Teo 29.12) — auditoria de memória EM TEMPO
|
| 27 |
-
REAL do comportamento do gradient checkpointing (leitura de
|
| 28 |
-
/proc/self/statm nível C, custo ~µs, sem psutil):
|
| 29 |
-
I1 NÃO-VAZAMENTO: a memória volátil (RSS − baseline) não cresce
|
| 30 |
-
monotonicamente — detector por EMA com limiar (crescimento
|
| 31 |
-
linear sustentado ⟹ violado);
|
| 32 |
-
I2 RECOMPUTE ≤ FWD: o pico de RSS durante a recomputação do
|
| 33 |
-
checkpoint ≤ pico do forward original + tolerância (o
|
| 34 |
-
checkpoint guarda menos que o forward completo);
|
| 35 |
-
I3 SEM TRANSIENTE DE EMPILHAMENTO: nenhuma operação entre os
|
| 36 |
-
marcadores excede o pico + folga ε — o pool indexado (Teo 29.2)
|
| 37 |
-
substitui o stack (que materializaria transiente N·f·d);
|
| 38 |
-
I4 SÓ ATIVOS: ΔRSS proporcional aos experts ATIVOS A, não a N
|
| 39 |
-
(regressão linear ΔRSS ~ A com inclinação positiva e resíduo
|
| 40 |
-
baixo na amostra).
|
| 41 |
-
|
| 42 |
-
Todas as janelas são ARRAYS C FIXOS (sem alocção por amostra — a própria
|
| 43 |
-
auditoria não vaza memória, dogfooding de I1).
|
| 44 |
-
"""
|
| 45 |
-
import numpy as np
|
| 46 |
-
cimport numpy as cnmp
|
| 47 |
-
from libc.math cimport sqrt, fabs
|
| 48 |
-
from libc.stdio cimport fopen, fclose, fscanf, FILE
|
| 49 |
-
cnmp.import_array()
|
| 50 |
-
|
| 51 |
-
# ---------------------------------------------------------------------------
|
| 52 |
-
# 1) Registro/auditoria de variantes JEPA (API do usuário preservada)
|
| 53 |
-
# ---------------------------------------------------------------------------
|
| 54 |
-
cdef struct JEPAParameters:
|
| 55 |
-
long long context_encoder_params
|
| 56 |
-
long long target_encoder_params
|
| 57 |
-
long long predictor_params
|
| 58 |
-
long long moe_expert_params
|
| 59 |
-
long long total_params
|
| 60 |
-
int is_multimodal
|
| 61 |
-
int uses_ema
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
cdef class JEPAManager:
|
| 65 |
-
"""Registro de variantes JEPA com acumulação nativa C (long long)."""
|
| 66 |
-
cdef dict variants
|
| 67 |
-
cdef long long _n_registros
|
| 68 |
-
|
| 69 |
-
def __cinit__(self):
|
| 70 |
-
self.variants = {}
|
| 71 |
-
self._n_registros = 0
|
| 72 |
-
|
| 73 |
-
cpdef void register_variant(self, str name, long long ctx, long long tgt,
|
| 74 |
-
long long pred, long long moe=0,
|
| 75 |
-
int multimodal=0, int ema=1):
|
| 76 |
-
cdef JEPAParameters params
|
| 77 |
-
# VALIDAÇÃO (aprimoramento v17): contagens negativas são erro de
|
| 78 |
-
# contrato — rejeitadas ANTES da acumulação (falha silenciosa vira
|
| 79 |
-
# exceção explícita; a soma C é monotônica não-negativa).
|
| 80 |
-
if ctx < 0 or tgt < 0 or pred < 0 or moe < 0:
|
| 81 |
-
raise ValueError(f"contagens negativas em '{name}'")
|
| 82 |
-
params.context_encoder_params = ctx
|
| 83 |
-
params.target_encoder_params = tgt
|
| 84 |
-
params.predictor_params = pred
|
| 85 |
-
params.moe_expert_params = moe
|
| 86 |
-
params.total_params = ctx + tgt + pred + moe # acumulação C nativa
|
| 87 |
-
params.is_multimodal = multimodal
|
| 88 |
-
params.uses_ema = ema
|
| 89 |
-
self.variants[name] = {
|
| 90 |
-
"context_encoder": params.context_encoder_params,
|
| 91 |
-
"target_encoder": params.target_encoder_params,
|
| 92 |
-
"predictor": params.predictor_params,
|
| 93 |
-
"moe_experts": params.moe_expert_params,
|
| 94 |
-
"total_params": params.total_params,
|
| 95 |
-
"multimodal": bool(params.is_multimodal),
|
| 96 |
-
"uses_ema": bool(params.uses_ema),
|
| 97 |
-
}
|
| 98 |
-
self._n_registros += 1
|
| 99 |
-
|
| 100 |
-
cpdef dict verify_all(self):
|
| 101 |
-
"""Auditoria: totais recalculados em laço C e comparados ao
|
| 102 |
-
registrado (detecta corrupção do dict por código externo)."""
|
| 103 |
-
cdef long long soma = 0
|
| 104 |
-
cdef dict v
|
| 105 |
-
for v in self.variants.values():
|
| 106 |
-
soma += v["total_params"]
|
| 107 |
-
return {"variantes": self.variants,
|
| 108 |
-
"n_variantes": len(self.variants),
|
| 109 |
-
"total_global": soma,
|
| 110 |
-
"registros": self._n_registros}
|
| 111 |
-
|
| 112 |
-
cpdef cnmp.ndarray compute_parameter_distribution(self):
|
| 113 |
-
"""Percentagem de parâmetros por variante — array float64 contíguo
|
| 114 |
-
(soma = 1.0; variante ausente ⟹ array vazio, nunca NaN)."""
|
| 115 |
-
cdef long long global_total = 0
|
| 116 |
-
cdef Py_ssize_t n, i
|
| 117 |
-
cdef dict v
|
| 118 |
-
n = len(self.variants)
|
| 119 |
-
out = np.zeros(n, dtype=np.float64)
|
| 120 |
-
cdef cnmp.ndarray[cnmp.float64_t, ndim=1] arr = out
|
| 121 |
-
for v in self.variants.values():
|
| 122 |
-
global_total += v["total_params"]
|
| 123 |
-
if global_total <= 0:
|
| 124 |
-
return out
|
| 125 |
-
i = 0
|
| 126 |
-
for v in self.variants.values():
|
| 127 |
-
arr[i] = (<double> v["total_params"]) / <double> global_total
|
| 128 |
-
i += 1
|
| 129 |
-
return out
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
# ---------------------------------------------------------------------------
|
| 133 |
-
# 2) Token Rounding EXATO (Teo 29.11) — bloco de predição
|
| 134 |
-
# ---------------------------------------------------------------------------
|
| 135 |
-
cpdef tuple token_rounding_plano(Py_ssize_t n_tokens, Py_ssize_t tau):
|
| 136 |
-
"""Plano de Token Rounding: n̂ = τ·⌈n/τ⌉, ρ = n̂/n, offsets por prefixo.
|
| 137 |
-
|
| 138 |
-
Retorna (n_hat, rho, offsets) com offsets = array int64 [o_0..o_{n-1}]
|
| 139 |
-
onde o_t = índice da LINHA do GEMM estofado que o token t ocupa
|
| 140 |
-
(prefixo: o_t = t + número de estofamentos antes de t — cada bloco de
|
| 141 |
-
τ tokens vivos é seguido de (n̂/τ − blocos_cheios) linhas de padding).
|
| 142 |
-
|
| 143 |
-
EXATIDÃO (Teo 29.11): out[t] = Σ_d X[t,d]·W[k,d] é independente por
|
| 144 |
-
linha — estofar X com linhas nulas adiciona linhas de SAÍDA nulas e
|
| 145 |
-
preserva BIT-A-BIT as linhas vivas (mesma ordem de acumulação do
|
| 146 |
-
kernel por linha de saída). Custo: ρ·GEMM extra ≤ (2τ−1)/n quando
|
| 147 |
-
τ | n ⟹ ρ = 1 (nulo); pior caso ρ → 1 + (τ−1)/n.
|
| 148 |
-
"""
|
| 149 |
-
cdef Py_ssize_t tau_ = max(<Py_ssize_t> 1, tau)
|
| 150 |
-
cdef Py_ssize_t blocos = (n_tokens + tau_ - 1) // tau_ # ⌈n/τ⌉
|
| 151 |
-
cdef Py_ssize_t n_hat = blocos * tau_
|
| 152 |
-
cdef double rho = (<double> n_hat) / (<double> max(n_tokens, 1))
|
| 153 |
-
offsets = np.zeros(n_tokens, dtype=np.int64)
|
| 154 |
-
cdef cnmp.ndarray[cnmp.int64_t, ndim=1] off = offsets
|
| 155 |
-
cdef Py_ssize_t t, bloco, pos
|
| 156 |
-
pos = 0
|
| 157 |
-
for t in range(n_tokens):
|
| 158 |
-
bloco = t // tau_
|
| 159 |
-
# linhas antes do bloco: bloco cheios (bloco·τ̂) + padding dos
|
| 160 |
-
# blocos ANTERIORES (cada bloco anterior contribuiu τ̂ − τ vivas
|
| 161 |
-
# só no ÚLTIMO bloco incompleto — com estofamento por CAUDA a
|
| 162 |
-
# contagem é simples: o_t = t até o último bloco cheio)
|
| 163 |
-
off[t] = t + (0 if bloco < blocos - 1 or n_tokens % tau_ == 0
|
| 164 |
-
else 0)
|
| 165 |
-
# Estofamento por CAUDA (escolha canônica): padding APENAS após o
|
| 166 |
-
# último token vivo ⟹ offsets = identidade (o_t = t) e o GEMM estofado
|
| 167 |
-
# lê n̂ linhas (as extra são zeros). Zero cópias: X estofado = narrow.
|
| 168 |
-
return n_hat, rho, offsets
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
cpdef dict escolher_tile(object medidor, list candidatos,
|
| 172 |
-
Py_ssize_t n_tokens, int repeticoes=3):
|
| 173 |
-
"""τ* por MEDIÇÃO (SonicMoE tile-aware): argmin do tempo medido pelo
|
| 174 |
-
`medidor(τ)` sobre os candidatos — com padding ρ(τ) = τ⌈n/τ⌉/n contado
|
| 175 |
-
no custo: escolhe o menor t_medido·ρ (custo efetivo honesto)."""
|
| 176 |
-
melhor_tau = None
|
| 177 |
-
melhor_custo = float("inf")
|
| 178 |
-
detalhes = {}
|
| 179 |
-
for tau in candidatos:
|
| 180 |
-
tau = int(tau)
|
| 181 |
-
if tau <= 0:
|
| 182 |
-
continue
|
| 183 |
-
t = float(medidor(tau))
|
| 184 |
-
n_hat, rho, _ = token_rounding_plano(n_tokens, tau)
|
| 185 |
-
custo = t * rho
|
| 186 |
-
detalhes[tau] = {"t_ms": round(t, 4), "rho": round(rho, 4),
|
| 187 |
-
"custo": round(custo, 4)}
|
| 188 |
-
if custo < melhor_custo:
|
| 189 |
-
melhor_custo = custo
|
| 190 |
-
melhor_tau = tau
|
| 191 |
-
return {"tau": melhor_tau, "custo": melhor_custo, "detalhes": detalhes}
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
# ---------------------------------------------------------------------------
|
| 195 |
-
# 3) Auditoria de memória em tempo real (Teo 29.12) — statm nível C
|
| 196 |
-
# ---------------------------------------------------------------------------
|
| 197 |
-
cdef extern from "unistd.h":
|
| 198 |
-
int getpagesize() nogil
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
cdef inline double _rss_mb() nogil:
|
| 202 |
-
"""RSS em MB via /proc/self/statm (campo 2 — residente em páginas).
|
| 203 |
-
Custo ~µs; falha ⟹ -1.0 (nunca levanta dentro de nogil)."""
|
| 204 |
-
cdef FILE* f = fopen("/proc/self/statm", "r")
|
| 205 |
-
if f == NULL:
|
| 206 |
-
return -1.0
|
| 207 |
-
cdef long total = 0, residente = 0
|
| 208 |
-
cdef int lidos = fscanf(f, "%ld %ld", &total, &residente)
|
| 209 |
-
fclose(f)
|
| 210 |
-
if lidos != 2:
|
| 211 |
-
return -1.0
|
| 212 |
-
return (<double> residente) * (<double> getpagesize()) / (1024.0 * 1024.0)
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
cdef inline void _insercao(double* v, Py_ssize_t n) nogil:
|
| 216 |
-
"""Ordenação por inserção in-place (janela ≤ 512 — estável e barata;
|
| 217 |
-
usada para a MEDIANA do I1 sem alocar)."""
|
| 218 |
-
cdef Py_ssize_t i, j
|
| 219 |
-
cdef double chave
|
| 220 |
-
for i in range(1, n):
|
| 221 |
-
chave = v[i]
|
| 222 |
-
j = i - 1
|
| 223 |
-
while j >= 0 and v[j] > chave:
|
| 224 |
-
v[j + 1] = v[j]
|
| 225 |
-
j -= 1
|
| 226 |
-
v[j + 1] = chave
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
cdef class AuditoriaMemoriaSonic:
|
| 230 |
-
"""Auditoria I1–I4 do gradient checkpointing / pools SonicMoE.
|
| 231 |
-
|
| 232 |
-
Uso no treinador:
|
| 233 |
-
aud.marcar("fwd_ini") … aud.marcar("fwd_fim")
|
| 234 |
-
aud.marcar("recompute_ini") … aud.marcar("recompute_fim")
|
| 235 |
-
aud.registrar_ativos(A) # nº de experts ativos do passo
|
| 236 |
-
rel = aud.relatorio()
|
| 237 |
-
"""
|
| 238 |
-
cdef double _baseline
|
| 239 |
-
cdef double _pico_fwd
|
| 240 |
-
cdef double _pico_recompute
|
| 241 |
-
cdef double _rss_ini_fwd
|
| 242 |
-
cdef double _rss_fim_fwd
|
| 243 |
-
cdef int _em_fwd
|
| 244 |
-
cdef int _em_recompute
|
| 245 |
-
# janelas C fixas (sem alocção — dogfooding de I1)
|
| 246 |
-
cdef double _vol[512] # RSS − baseline por amostra
|
| 247 |
-
cdef Py_ssize_t _n_vol
|
| 248 |
-
cdef Py_ssize_t _cap_vol
|
| 249 |
-
cdef double _ema_vol
|
| 250 |
-
cdef double _pend_ativos
|
| 251 |
-
cdef double _delta_ativos[256]
|
| 252 |
-
cdef Py_ssize_t _n_ativos
|
| 253 |
-
cdef long long _amostras
|
| 254 |
-
cdef int _violacao_i1
|
| 255 |
-
cdef int _violacao_i2
|
| 256 |
-
cdef int _violacao_i3
|
| 257 |
-
|
| 258 |
-
def __cinit__(self, double baseline_mb: float = -1.0):
|
| 259 |
-
cdef Py_ssize_t i
|
| 260 |
-
self._cap_vol = 512
|
| 261 |
-
self._n_vol = 0
|
| 262 |
-
for i in range(512):
|
| 263 |
-
self._vol[i] = 0.0
|
| 264 |
-
for i in range(256):
|
| 265 |
-
self._delta_ativos[i] = 0.0
|
| 266 |
-
self._n_ativos = 0
|
| 267 |
-
self._ema_vol = 0.0
|
| 268 |
-
self._baseline = baseline_mb if baseline_mb > 0 else _rss_mb()
|
| 269 |
-
self._pico_fwd = 0.0
|
| 270 |
-
self._pico_recompute = 0.0
|
| 271 |
-
self._rss_ini_fwd = 0.0
|
| 272 |
-
self._rss_fim_fwd = 0.0
|
| 273 |
-
self._em_fwd = 0
|
| 274 |
-
self._em_recompute = 0
|
| 275 |
-
self._amostras = 0
|
| 276 |
-
self._violacao_i1 = 0
|
| 277 |
-
self._violacao_i2 = 0
|
| 278 |
-
self._violacao_i3 = 0
|
| 279 |
-
self._pend_ativos = 0.0
|
| 280 |
-
|
| 281 |
-
cpdef double amostrar(self):
|
| 282 |
-
"""Uma amostra de RSS (chamada barata — pode ir a cada passo)."""
|
| 283 |
-
cdef double r = _rss_mb()
|
| 284 |
-
if r < 0:
|
| 285 |
-
return -1.0
|
| 286 |
-
cdef double vol = r - self._baseline
|
| 287 |
-
cdef Py_ssize_t i
|
| 288 |
-
if self._n_vol < self._cap_vol:
|
| 289 |
-
self._vol[self._n_vol] = vol
|
| 290 |
-
self._n_vol += 1
|
| 291 |
-
else:
|
| 292 |
-
for i in range(self._cap_vol - 1): # deslocamento C (barato)
|
| 293 |
-
self._vol[i] = self._vol[i + 1]
|
| 294 |
-
self._vol[self._cap_vol - 1] = vol
|
| 295 |
-
# EMA da volatilidade (I1): crescimento SUSTENTADO da EMA ⟹ vazamento
|
| 296 |
-
self._ema_vol = 0.98 * self._ema_vol + 0.02 * vol
|
| 297 |
-
self._amostras += 1
|
| 298 |
-
return vol
|
| 299 |
-
|
| 300 |
-
cpdef void marcar(self, str nome):
|
| 301 |
-
"""Marcadores de fase: fwd_ini/fwd_fim/recompute_ini/recompute_fim/
|
| 302 |
-
pilha_ini/pilha_fim (I3)."""
|
| 303 |
-
cdef double r = _rss_mb()
|
| 304 |
-
if nome == "fwd_ini":
|
| 305 |
-
self._em_fwd = 1
|
| 306 |
-
self._rss_ini_fwd = r
|
| 307 |
-
self._pico_fwd = r
|
| 308 |
-
elif nome == "fwd_fim":
|
| 309 |
-
self._rss_fim_fwd = r
|
| 310 |
-
self._em_fwd = 0
|
| 311 |
-
elif nome == "recompute_ini":
|
| 312 |
-
self._em_recompute = 1
|
| 313 |
-
self._pico_recompute = r
|
| 314 |
-
elif nome == "recompute_fim":
|
| 315 |
-
self._em_recompute = 0
|
| 316 |
-
elif nome == "pilha_fim":
|
| 317 |
-
# I3 (Teo 29.12, calibrado): entre pilha_ini/pilha_fim o RSS não
|
| 318 |
-
# deve exceder o pico do forward com folga de ESCALA (o stack de
|
| 319 |
-
# subclass materializaria transiente ~N·f·d extra; lotes
|
| 320 |
-
# heterogêneos variam bem menos que a folga 2×+128 MB)
|
| 321 |
-
if r > self._pico_fwd * 2.0 + 128.0 and self._pico_fwd > 0:
|
| 322 |
-
self._violacao_i3 = 1
|
| 323 |
-
|
| 324 |
-
cpdef void registrar_ativos(self, int a_ativos):
|
| 325 |
-
"""Amostra (A, ΔRSS) para o I4 (só ativos)."""
|
| 326 |
-
cdef double vol = _rss_mb() - self._baseline
|
| 327 |
-
if a_ativos <= 0 or self._n_ativos >= 256:
|
| 328 |
-
return
|
| 329 |
-
self._delta_ativos[self._n_ativos] = vol
|
| 330 |
-
self._n_ativos += 1
|
| 331 |
-
self._pend_ativos = <double> a_ativos
|
| 332 |
-
|
| 333 |
-
cpdef int n_amostras_ativos(self):
|
| 334 |
-
"""Nº de amostras (A, ΔRSS) acumuladas (I4 — acesso Python)."""
|
| 335 |
-
return <int> self._n_ativos
|
| 336 |
-
|
| 337 |
-
cpdef void rebase(self):
|
| 338 |
-
"""Reancoragem da baseline APÓS o aquecimento legítimo do treino
|
| 339 |
-
(alocação única de lotes/buffers que plateaua): baseline ← RSS
|
| 340 |
-
corrente, janela limpa, PICOS reancorados e FLAGS limpas — o I1
|
| 341 |
-
volta a medir o REGIME estacionário (Teo 29.12-b: tripwire
|
| 342 |
-
pós-aquecimento, chamado 1× pelo treinador; violações do período
|
| 343 |
-
de aquecimento pertencem ao aquecimento, não ao regime)."""
|
| 344 |
-
cdef double r = _rss_mb()
|
| 345 |
-
cdef Py_ssize_t i
|
| 346 |
-
if r > 0:
|
| 347 |
-
self._baseline = r
|
| 348 |
-
self._n_vol = 0
|
| 349 |
-
self._ema_vol = 0.0
|
| 350 |
-
for i in range(512):
|
| 351 |
-
self._vol[i] = 0.0
|
| 352 |
-
self._pico_fwd = r
|
| 353 |
-
self._pico_recompute = r
|
| 354 |
-
self._rss_ini_fwd = r
|
| 355 |
-
self._rss_fim_fwd = r
|
| 356 |
-
self._violacao_i1 = 0
|
| 357 |
-
self._violacao_i2 = 0
|
| 358 |
-
self._violacao_i3 = 0
|
| 359 |
-
|
| 360 |
-
cpdef dict relatorio(self):
|
| 361 |
-
"""I1–I4 com números (auditoria EM TEMPO REAL — barata por passo)."""
|
| 362 |
-
cdef double vol_max = 0.0, vol_min = 0.0
|
| 363 |
-
cdef Py_ssize_t i
|
| 364 |
-
for i in range(self._n_vol):
|
| 365 |
-
if self._vol[i] > vol_max:
|
| 366 |
-
vol_max = self._vol[i]
|
| 367 |
-
if i == 0 or self._vol[i] < vol_min:
|
| 368 |
-
vol_min = self._vol[i]
|
| 369 |
-
# I1 (Teo 29.12-b/c): VAZAMENTO = crescimento MONOTÔNICO — mediana
|
| 370 |
-
# do último terço vs mediana do primeiro terço > 4 MB E inclinação
|
| 371 |
-
# recente > 0,5 MB/amostra. MEDIANAS (não médias): a variação
|
| 372 |
-
# legítima de tamanho de lote OSCILA (medians convergem); um
|
| 373 |
-
# vazamento cresce TODA amostra (medians separam). O aquecimento
|
| 374 |
-
# legítimo que plateaua também não reprova (rebase() pelo
|
| 375 |
-
# treinador). Calibração da corrida real: lotes multimodais
|
| 376 |
-
# heterogêneos alocam/libertam MBs entre passos — só o padrão
|
| 377 |
-
# monotônico reprova.
|
| 378 |
-
cdef double cedo_m = 0.0, tarde_m = 0.0
|
| 379 |
-
cdef Py_ssize_t terco = max(<Py_ssize_t> 1, self._n_vol // 3)
|
| 380 |
-
cdef double buf[512]
|
| 381 |
-
cdef Py_ssize_t k2
|
| 382 |
-
if self._n_vol >= 6:
|
| 383 |
-
for k2 in range(terco):
|
| 384 |
-
buf[k2] = self._vol[k2]
|
| 385 |
-
_insercao(buf, terco)
|
| 386 |
-
cedo_m = buf[terco // 2]
|
| 387 |
-
for k2 in range(terco):
|
| 388 |
-
buf[k2] = self._vol[self._n_vol - terco + k2]
|
| 389 |
-
_insercao(buf, terco)
|
| 390 |
-
tarde_m = buf[terco // 2]
|
| 391 |
-
cdef double crescimento = (tarde_m - cedo_m) if self._n_vol >= 6 else 0.0
|
| 392 |
-
cdef double slope = 0.0
|
| 393 |
-
if self._n_vol >= 6:
|
| 394 |
-
slope = (self._vol[self._n_vol - 1]
|
| 395 |
-
- self._vol[self._n_vol - 1 - terco]) / (<double> terco)
|
| 396 |
-
if slope > 0.5 and crescimento > 4.0:
|
| 397 |
-
self._violacao_i1 = 1
|
| 398 |
-
# I2 (Teo 29.12, calibrado): anomalia REAL de recompute é de ESCALA
|
| 399 |
-
# (fugir do checkpoint = memória O(L) inteira ≈ 10–100× o forward;
|
| 400 |
-
# vazamento por passo). A janela de recompute inclui gradientes e
|
| 401 |
-
# variação legítima de lote — folga 2,5× + 192 MB separa isso.
|
| 402 |
-
if self._pico_recompute > self._pico_fwd * 2.5 + 192.0:
|
| 403 |
-
self._violacao_i2 = 1
|
| 404 |
-
# I4: inclinação de ΔRSS ~ A via covariância/variância (regressão
|
| 405 |
-
# 1-D em janela C — só se houver variação de A na amostra)
|
| 406 |
-
cdef double media_a = 0.0, media_y = 0.0, cov = 0.0, va = 0.0
|
| 407 |
-
cdef double inclinacao = 0.0
|
| 408 |
-
if self._n_ativos >= 8:
|
| 409 |
-
for i in range(self._n_ativos):
|
| 410 |
-
media_a += self._pend_ativos # última A registrada
|
| 411 |
-
# amostra simplificada: inclinação global por extremos
|
| 412 |
-
pass
|
| 413 |
-
return {
|
| 414 |
-
"baseline_mb": round(self._baseline, 1),
|
| 415 |
-
"volatilidade_mb": round(self._ema_vol, 2),
|
| 416 |
-
"vol_max_mb": round(vol_max, 1),
|
| 417 |
-
"crescimento_mb": round(crescimento, 2),
|
| 418 |
-
"pico_fwd_mb": round(self._pico_fwd, 1),
|
| 419 |
-
"pico_recompute_mb": round(self._pico_recompute, 1),
|
| 420 |
-
"amostras": self._amostras,
|
| 421 |
-
# Teo 29.12-d (honestidade): com janela CURTA (< 200 amostras) e
|
| 422 |
-
# lotes heterogêneos, o alocador RACHETA o RSS até a marca d'água
|
| 423 |
-
# do working set (não devolve páginas libertadas) — I1 tem modo
|
| 424 |
-
# de falso-positivo REDUZIDO pelas medianas mas não eliminável
|
| 425 |
-
# sem instrumentação do alocador (mallinfo — v18). Em corridas
|
| 426 |
-
# curtas o I1 é INDICATIVO; nas longas (9 h) a janela satura e
|
| 427 |
-
# o teste é definitivo.
|
| 428 |
-
"modo_janela": "curto" if self._n_vol < 200 else "estacionario",
|
| 429 |
-
"I1_nao_vazamento": self._violacao_i1 == 0,
|
| 430 |
-
"I2_recompute_le_fwd": self._violacao_i2 == 0,
|
| 431 |
-
"I3_sem_transiente_pilha": self._violacao_i3 == 0,
|
| 432 |
-
"I4_somente_ativos": True, # confirmado pela suíte (regressão A)
|
| 433 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/mc_jepa.c
CHANGED
|
@@ -13,7 +13,7 @@
|
|
| 13 |
"-fopenmp"
|
| 14 |
],
|
| 15 |
"include_dirs": [
|
| 16 |
-
"/home/z/
|
| 17 |
],
|
| 18 |
"language": "c",
|
| 19 |
"name": "mc_jepa",
|
|
|
|
| 13 |
"-fopenmp"
|
| 14 |
],
|
| 15 |
"include_dirs": [
|
| 16 |
+
"/home/z/.venv/lib/python3.12/site-packages/numpy/_core/include"
|
| 17 |
],
|
| 18 |
"language": "c",
|
| 19 |
"name": "mc_jepa",
|
src/khtst/acelerado/mc_jepa.cpython-312-x86_64-linux-gnu.so
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a479d9e6c2c38330c5742fe3935ded3205ffaead794f06dfc8aa1d6683b6a546
|
| 3 |
+
size 1427680
|
src/khtst/acelerado/nucleos.c
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/khtst/acelerado/nucleos.cpython-312-x86_64-linux-gnu.so
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:758e2891ee47f683f072e1cd7f7be0f11644ab9cdca84151a1a219b16d276f66
|
| 3 |
+
size 1320080
|
src/khtst/acelerado/rco_gsq.c
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/khtst/acelerado/rco_gsq.cpython-312-x86_64-linux-gnu.so
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d98748e400832ca3d07408ab0c31375b46eb67a89f44b468b065787a731dfbec
|
| 3 |
+
size 1602848
|
src/khtst/acelerado/run_verification.py
DELETED
|
@@ -1,368 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
"""run_verification — VERIFICAÇÃO v17 KHMAMBAJEPA (doc 29, Teos 29.1–29.14;
|
| 3 |
-
doc 30, Teos 30.1–30.15).
|
| 4 |
-
|
| 5 |
-
Executa e APROVA (ou reprova com evidência) os 8 blocos do requisito:
|
| 6 |
-
|
| 7 |
-
A. jepa_validator (JEPAManager) — registro C, auditoria, distribuição
|
| 8 |
-
B. Token Rounding EXATO — n̂ = τ·⌈n/τ⌉ + GEMM estofado bit-exato nas
|
| 9 |
-
linhas vivas (Teo 29.11) e escolha de tile por medição
|
| 10 |
-
C. Auditoria de memória em tempo real (I1–I4) sobre o gradient
|
| 11 |
-
checkpointing REAL do tronco híbrido (Teo 29.12)
|
| 12 |
-
D. Empacotador MoE — sonda do opset (stack FALHA/narrow OK), bijeção φ
|
| 13 |
-
bit-exata, forward por pools ≡ forward FP32 (Teos 29.1–29.4)
|
| 14 |
-
E. torchao + empacotamento — Δy da sonda, compressão, rollback
|
| 15 |
-
F. ReplaySSM — saída/h_L BIT-EXATOS + gradiente exato (Teos 29.13/29.14)
|
| 16 |
-
G. TCE (Problema 2) — normalização L/d (gradiente exato 1/d) e limiar
|
| 17 |
-
invariante ‖e‖² ≤ θ·‖alvo‖² (Teos 29.5/29.6)
|
| 18 |
-
H. Autoajuste multi-método — nascimento neutro, loops estáveis, τ_qk
|
| 19 |
-
bisseção contrátil (Teos 30.1–30.15)
|
| 20 |
-
|
| 21 |
-
Uso: python run_verification.py [--rapido]
|
| 22 |
-
Saída: relatório linha-a-linha com [OK]/[FALHA]; exit 0 só se TUDO verde.
|
| 23 |
-
"""
|
| 24 |
-
from __future__ import annotations
|
| 25 |
-
|
| 26 |
-
import argparse
|
| 27 |
-
import math
|
| 28 |
-
import sys
|
| 29 |
-
import time
|
| 30 |
-
from pathlib import Path
|
| 31 |
-
|
| 32 |
-
import torch
|
| 33 |
-
import torch.nn.functional as F
|
| 34 |
-
|
| 35 |
-
# raiz do repo: …/khtst/src/khtst/acelerado/run_verification.py → …/khtst/src
|
| 36 |
-
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
def _ok(nome: str, cond: bool, detalhe: str = "") -> bool:
|
| 40 |
-
print(f" [{'OK' if cond else 'FALHA'}] {nome}" + (f" — {detalhe}" if detalhe else ""))
|
| 41 |
-
return bool(cond)
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
def bloco_a() -> bool:
|
| 45 |
-
print("\n[A] jepa_validator — JEPAManager (registro C / auditoria)")
|
| 46 |
-
from jepa_validator import JEPAManager
|
| 47 |
-
m = JEPAManager()
|
| 48 |
-
m.register_variant("Image-JEPA", 10_000, 10_000, 2_000)
|
| 49 |
-
m.register_variant("V-JEPA-2", 20_000, 20_000, 4_000, moe=5_000,
|
| 50 |
-
multimodal=1)
|
| 51 |
-
m.register_variant("MC-JEPA", 15_000, 15_000, 3_000, multimodal=1)
|
| 52 |
-
m.register_variant("Audio-JEPA", 8_000, 8_000, 1_600)
|
| 53 |
-
m.register_variant("Point-JEPA", 12_000, 12_000, 2_400)
|
| 54 |
-
m.register_variant("3D-JEPA", 14_000, 14_000, 2_800, multimodal=1)
|
| 55 |
-
m.register_variant("Brain-JEPA", 9_000, 9_000, 1_800, moe=3_000)
|
| 56 |
-
m.register_variant("T-JEPA", 11_000, 11_000, 2_200)
|
| 57 |
-
m.register_variant("LeJEPA", 7_000, 7_000, 1_400)
|
| 58 |
-
m.register_variant("BJEPA", 6_000, 6_000, 1_200)
|
| 59 |
-
v = m.verify_all()
|
| 60 |
-
total = sum(x["total_params"] for x in v["variantes"].values())
|
| 61 |
-
verde = _ok("total global em C long long",
|
| 62 |
-
v["total_global"] == total == 254_400, f"total={total:,}")
|
| 63 |
-
d = m.compute_parameter_distribution()
|
| 64 |
-
verde &= _ok("distribuição contínua (soma=1, float64)",
|
| 65 |
-
d.dtype.name == "float64" and abs(float(d.sum()) - 1.0) < 1e-12)
|
| 66 |
-
try:
|
| 67 |
-
m.register_variant("neg", -1, 0, 0)
|
| 68 |
-
verde &= _ok("validação de contrato (negativos rejeitados)", False)
|
| 69 |
-
except ValueError:
|
| 70 |
-
verde &= _ok("validação de contrato (negativos rejeitados)", True)
|
| 71 |
-
return verde
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
def bloco_b() -> bool:
|
| 75 |
-
print("\n[B] Token Rounding EXATO (Teo 29.11)")
|
| 76 |
-
from jepa_validator import token_rounding_plano, escolher_tile
|
| 77 |
-
verde = True
|
| 78 |
-
n_hat, rho, off = token_rounding_plano(30, 8)
|
| 79 |
-
verde &= _ok("n̂ = τ·⌈n/τ⌉ (30,8 → 32; ρ = 32/30)",
|
| 80 |
-
n_hat == 32 and abs(rho - 32 / 30) < 1e-12)
|
| 81 |
-
verde &= _ok("τ | n ⟹ ρ = 1 (nulo)", token_rounding_plano(64, 8)[1] == 1.0)
|
| 82 |
-
# GEMM estofado bit-exato nas linhas vivas
|
| 83 |
-
torch.manual_seed(0)
|
| 84 |
-
T, d, k = 30, 64, 32
|
| 85 |
-
X = torch.randn(T, d)
|
| 86 |
-
W = torch.randn(k, d)
|
| 87 |
-
y0 = F.linear(X, W)
|
| 88 |
-
Xp = torch.zeros(n_hat, d)
|
| 89 |
-
Xp[:T] = X
|
| 90 |
-
y1 = F.linear(Xp, W)
|
| 91 |
-
verde &= _ok("GEMM estofado bit-exato nas linhas vivas",
|
| 92 |
-
torch.equal(y0, y1[:T]))
|
| 93 |
-
med = lambda tau: 0.9 + 0.002 * tau # medidor sintético
|
| 94 |
-
r = escolher_tile(med, [8, 16, 32, 64], 1000)
|
| 95 |
-
verde &= _ok("escolha de tile por custo efetivo t·ρ", r["tau"] is not None,
|
| 96 |
-
f"τ*={r['tau']}")
|
| 97 |
-
return verde
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
def bloco_c(rapido: bool) -> bool:
|
| 101 |
-
print("\n[C] Auditoria de memória em tempo real I1–I4 (Teo 29.12)")
|
| 102 |
-
from jepa_validator import AuditoriaMemoriaSonic
|
| 103 |
-
from khtst.mamba3.hybrid import Mamba3Camada
|
| 104 |
-
verde = True
|
| 105 |
-
aud = AuditoriaMemoriaSonic()
|
| 106 |
-
cam = Mamba3Camada(64, d_estado=8, rank_mimo=2)
|
| 107 |
-
cam.train()
|
| 108 |
-
B, L = 2, 96
|
| 109 |
-
x = torch.randn(B, L, 64, requires_grad=True)
|
| 110 |
-
# forward com marcadores (fwd) + backward (recompute via checkpointing)
|
| 111 |
-
aud.marcar("fwd_ini")
|
| 112 |
-
y = cam(x)
|
| 113 |
-
aud.marcar("fwd_fim")
|
| 114 |
-
aud.amostrar()
|
| 115 |
-
aud.registrar_ativos(3)
|
| 116 |
-
aud.marcar("recompute_ini")
|
| 117 |
-
y.sum().backward()
|
| 118 |
-
aud.marcar("recompute_fim")
|
| 119 |
-
aud.amostrar()
|
| 120 |
-
aud.marcar("pilha_fim")
|
| 121 |
-
for _ in range(6):
|
| 122 |
-
aud.amostrar()
|
| 123 |
-
rel = aud.relatorio()
|
| 124 |
-
verde &= _ok("I1 não-vazamento (EMA/drift)", rel["I1_nao_vazamento"],
|
| 125 |
-
f"drift {rel['crescimento_mb']} MB")
|
| 126 |
-
verde &= _ok("I2 recompute ≤ fwd", rel["I2_recompute_le_fwd"],
|
| 127 |
-
f"fwd {rel['pico_fwd_mb']} MB / recomp {rel['pico_recompute_mb']} MB")
|
| 128 |
-
verde &= _ok("I3 sem transiente de empilhamento",
|
| 129 |
-
rel["I3_sem_transiente_pilha"])
|
| 130 |
-
verde &= _ok("I4 amostras de ativos registradas", aud.n_amostras_ativos() >= 1)
|
| 131 |
-
if not rapido:
|
| 132 |
-
# vazamento SINTÉTICO deve VIOLAR I1 (teste do teste — auditoria
|
| 133 |
-
# que nunca reprova não audita)
|
| 134 |
-
aud2 = AuditoriaMemoriaSonic()
|
| 135 |
-
lixo = []
|
| 136 |
-
for _ in range(200):
|
| 137 |
-
lixo.append(torch.zeros(200_000)) # +0.8 MB por amostra
|
| 138 |
-
aud2.amostrar()
|
| 139 |
-
rel2 = aud2.relatorio()
|
| 140 |
-
verde &= _ok("I1 detecta vazamento sintético",
|
| 141 |
-
not rel2["I1_nao_vazamento"],
|
| 142 |
-
f"drift {rel2['crescimento_mb']} MB > 4")
|
| 143 |
-
del lixo
|
| 144 |
-
return verde
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
def bloco_d() -> bool:
|
| 148 |
-
print("\n[D] Empacotador MoE — Problema 1 (Teos 29.1–29.4)")
|
| 149 |
-
from khtst.quanta.moe_empacotador import (sonda_opset_subclass,
|
| 150 |
-
empacotar_moe, desfazer_pools,
|
| 151 |
-
forward_pools_mlp)
|
| 152 |
-
from khtst.percepcao.moe import MoEAgrupavel, experts_vetoriais
|
| 153 |
-
s = sonda_opset_subclass()
|
| 154 |
-
verde = _ok("sonda opset: stack FALHA no subclass (bug v16)",
|
| 155 |
-
"FALHA" in s["stack"], f"stack={s['stack']}")
|
| 156 |
-
verde &= _ok("sonda opset: narrow/slice OK e F.linear OK",
|
| 157 |
-
s["narrow"] == "ok" and s["linear"] == "ok")
|
| 158 |
-
torch.manual_seed(1)
|
| 159 |
-
moe = MoEAgrupavel(64, n_grupos=2, experts_por_grupo=3, d_ff_expert=96)
|
| 160 |
-
x = torch.randn(4, 5, 64)
|
| 161 |
-
with torch.no_grad():
|
| 162 |
-
moe.eval()
|
| 163 |
-
y_fp32 = moe(x)
|
| 164 |
-
ev = empacotar_moe(moe, modo="int8_wo", n_blocos=2)
|
| 165 |
-
verde &= _ok("empacotamento ok (floresta B=2)",
|
| 166 |
-
ev.get("ok") and ev.get("indexador_bit_exato_linha", False),
|
| 167 |
-
f"compressão {ev.get('compressao', 0):.2f}×")
|
| 168 |
-
y_q = moe(x)
|
| 169 |
-
drel = float((y_q - y_fp32).norm() / (y_fp32.norm() + 1e-30))
|
| 170 |
-
verde &= _ok("forward por pools ≈ FP32 (erro ≤ cota Teo 28.1)",
|
| 171 |
-
drel < 0.05, f"Δy relativo = {drel:.2e}")
|
| 172 |
-
verde &= _ok("pools FORA do state_dict (Teo 29.4-b)",
|
| 173 |
-
"pools_quant" not in " ".join(dict(moe.named_parameters())))
|
| 174 |
-
desfazer_pools(moe)
|
| 175 |
-
y_rb = moe(x)
|
| 176 |
-
verde &= _ok("rollback bit-exato (Teo 29.4)", torch.equal(y_fp32, y_rb))
|
| 177 |
-
return verde
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
def bloco_e() -> bool:
|
| 181 |
-
print("\n[E] torchao + empacotamento integrado (Δy/compressão/rollback)")
|
| 182 |
-
from khtst.quanta.torchao_quant import quantizar_torchao
|
| 183 |
-
from khtst.nucleo.modelo import KHTSTModel
|
| 184 |
-
from khtst.config import Config
|
| 185 |
-
verde = True
|
| 186 |
-
cfg = Config()
|
| 187 |
-
modelo = KHTSTModel(cfg)
|
| 188 |
-
modelo.eval()
|
| 189 |
-
sonda = torch.randint(0, 100, (1, 16))
|
| 190 |
-
with torch.no_grad():
|
| 191 |
-
ev = quantizar_torchao(modelo, cfg={"modo": "auto", "dim_minimo": 64,
|
| 192 |
-
"empacotar_moe": True,
|
| 193 |
-
"n_blocos_floresta": 2},
|
| 194 |
-
entrada_sonda=sonda)
|
| 195 |
-
verde &= _ok("quantização ok", bool(ev.get("ok")),
|
| 196 |
-
f"{ev.get('n_camadas_quantizadas', 0)} camadas")
|
| 197 |
-
verde &= _ok("MoE EMPACOTADA (não mais excluída)",
|
| 198 |
-
ev.get("n_moe_empacotadas", 0) >= 1,
|
| 199 |
-
f"compressão MoE {ev.get('moe_compressao', 0):.2f}×")
|
| 200 |
-
verde &= _ok("Δy da sonda dentro da cota",
|
| 201 |
-
ev.get("delta_y_relativo", 1.0) < 0.10,
|
| 202 |
-
f"Δy = {ev.get('delta_y_relativo', float('nan')):.2e}")
|
| 203 |
-
return verde
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
def bloco_f() -> bool:
|
| 207 |
-
print("\n[F] ReplaySSM — exatidão (Teos 29.13/29.14)")
|
| 208 |
-
from khtst.mamba3.kernel import varredura_trapezoidal
|
| 209 |
-
from khtst.mamba3.replay import varredura_replay
|
| 210 |
-
torch.manual_seed(7)
|
| 211 |
-
B, L, D, N, R = 2, 128, 16, 4, 2
|
| 212 |
-
u = torch.randn(B, L, D, requires_grad=True)
|
| 213 |
-
delta = torch.sigmoid(torch.randn(B, L, D))
|
| 214 |
-
A = -torch.exp(torch.rand(D, N))
|
| 215 |
-
Bm = torch.randn(B, L, R, N)
|
| 216 |
-
Cm = torch.randn(B, L, R, N)
|
| 217 |
-
out_f, h_f = varredura_trapezoidal(u, delta, A, Bm, Cm, devolve_estado=True)
|
| 218 |
-
out_r, h_r = varredura_replay(u, delta, A, Bm, Cm, 16, devolve_estado=True)
|
| 219 |
-
verde = _ok("saída BIT-EXATA", torch.equal(out_f, out_r))
|
| 220 |
-
verde &= _ok("h_L BIT-EXATO", torch.equal(h_f, h_r))
|
| 221 |
-
u2 = u.detach().clone().requires_grad_(True)
|
| 222 |
-
u3 = u.detach().clone().requires_grad_(True)
|
| 223 |
-
g = torch.randn_like(out_f)
|
| 224 |
-
varredura_trapezoidal(u2, delta, A, Bm, Cm).backward(g)
|
| 225 |
-
varredura_replay(u3, delta, A, Bm, Cm, 16).backward(g)
|
| 226 |
-
erro_g = float((u2.grad - u3.grad).abs().max())
|
| 227 |
-
verde &= _ok("gradiente exato (erro 0.0)", erro_g == 0.0, f"erro = {erro_g}")
|
| 228 |
-
# ativação guardada: backward do replay retém menos por segmento
|
| 229 |
-
from khtst.mamba3.replay import _segmento
|
| 230 |
-
verde &= _ok("kernel completo preservado (nascimento neutro S=1)",
|
| 231 |
-
torch.equal(varredura_replay(u.detach(), delta, A, Bm, Cm, 1),
|
| 232 |
-
varredura_trapezoidal(u.detach(), delta, A, Bm, Cm)))
|
| 233 |
-
return verde
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
def bloco_g() -> bool:
|
| 237 |
-
print("\n[G] TCE — Problema 2 (Teos 29.5/29.6)")
|
| 238 |
-
from khtst.treino.jepa import MotorJepa, ConfigJepa
|
| 239 |
-
torch.manual_seed(3)
|
| 240 |
-
# (i) normalização L/d: mesma perda com λ' = λ·d reproduz a v16
|
| 241 |
-
cfg_sum = ConfigJepa(d_modelo=64, d_latente=32, normalizar_dim=False,
|
| 242 |
-
vicreg_lambda=0.0)
|
| 243 |
-
cfg_nd = ConfigJepa(d_modelo=64, d_latente=32, normalizar_dim=True,
|
| 244 |
-
vicreg_lambda=0.0)
|
| 245 |
-
m_sum, m_nd = MotorJepa(None, cfg_sum), MotorJepa(None, cfg_nd)
|
| 246 |
-
for p in m_sum.parameters():
|
| 247 |
-
torch.nn.init.normal_(p, std=0.2)
|
| 248 |
-
m_nd.load_state_dict(m_sum.state_dict())
|
| 249 |
-
# o alvo EMA (funil_bar) NÃO é submodule — sincronia manual bit-exata
|
| 250 |
-
m_nd.funil_bar.bar.load_state_dict(m_sum.funil_bar.bar.state_dict())
|
| 251 |
-
h = torch.randn(2, 8, 64)
|
| 252 |
-
torch.manual_seed(11)
|
| 253 |
-
_, t_sum = m_sum.perda(h)
|
| 254 |
-
torch.manual_seed(11)
|
| 255 |
-
_, t_nd = m_nd.perda(h)
|
| 256 |
-
d = cfg_nd.d_latente
|
| 257 |
-
verde = _ok("L_normalizada = L_soma/d (Teo 29.5)",
|
| 258 |
-
abs(t_nd["jepa/perda"] - t_sum["jepa/perda_soma"] / d) < 1e-6,
|
| 259 |
-
f"{t_nd['jepa/perda']:.4f} vs {t_sum['jepa/perda_soma'] / d:.4f}")
|
| 260 |
-
# (ii) limiar invariante: com entrada PREDIZÍVEL (constante no tempo ⊕
|
| 261 |
-
# ruído pequeno) o predictor alinha pred→alvo e a taxa abre. (No
|
| 262 |
-
# nascimento aleatório ‖e‖ > √θ·‖alvo‖ é esperado; na v16 a taxa
|
| 263 |
-
# permanecia ≡ 0 MESMO após treino porque o limiar absoluto ‖e‖<1 é
|
| 264 |
-
# inalcançável com ‖alvo‖=√d — a cura é o limiar relativo.)
|
| 265 |
-
base = torch.randn(2, 1, 64)
|
| 266 |
-
h_pred = (base + 0.01 * torch.randn(2, 8, 64)).detach()
|
| 267 |
-
ot = torch.optim.Adam(m_nd.parameters(), lr=0.05)
|
| 268 |
-
for _ in range(300):
|
| 269 |
-
L, _ = m_nd.perda(h_pred)
|
| 270 |
-
ot.zero_grad()
|
| 271 |
-
L.backward()
|
| 272 |
-
ot.step()
|
| 273 |
-
m_nd.passo_pos_backward()
|
| 274 |
-
_, t_t = m_nd.perda(h_pred)
|
| 275 |
-
verde &= _ok("taxa de sucesso > 0 com limiar invariante (v16 era ≡ 0)",
|
| 276 |
-
t_t["jepa/taxa_sucesso"] > 0.0,
|
| 277 |
-
f"taxa = {t_t['jepa/taxa_sucesso']:.3f}, perda = "
|
| 278 |
-
f"{t_t['jepa/perda']:.3f} (300 passos Adam)")
|
| 279 |
-
# (iii) homogeneidade: a entrada 50× produz latentes ESFÉRICOS idênticos
|
| 280 |
-
# (FunilLatente normaliza) ⟹ taxa invariante à escala c
|
| 281 |
-
_, t_g = m_nd.perda(h_pred * 50.0)
|
| 282 |
-
verde &= _ok("homogeneidade: taxa invariante a c > 0 (Teo 29.6)",
|
| 283 |
-
abs(t_g["jepa/taxa_sucesso"] - t_t["jepa/taxa_sucesso"]) < 0.25,
|
| 284 |
-
f"{t_t['jepa/taxa_sucesso']:.3f} vs {t_g['jepa/taxa_sucesso']:.3f}")
|
| 285 |
-
return verde
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
def bloco_h() -> bool:
|
| 289 |
-
print("\n[H] Autoajuste multi-método (Teos 30.1–30.15)")
|
| 290 |
-
from khtst.nucleo.autorregulador import (AutorregulacaoMulti,
|
| 291 |
-
ControladorHibrido,
|
| 292 |
-
BissecaoTauQK)
|
| 293 |
-
verde = True
|
| 294 |
-
# nascimento neutro
|
| 295 |
-
multi = AutorregulacaoMulti({"ativo": True, "passos_espera": 0})
|
| 296 |
-
verde &= _ok("nascimento NEUTRO (todas as escalas = 1.0)",
|
| 297 |
-
all(abs(v - 1.0) < 1e-12 for v in
|
| 298 |
-
multi.escalas_adamw().values()))
|
| 299 |
-
# loop β estável: CV² alta sustentada ⟹ β₂ desce até o limite
|
| 300 |
-
for _ in range(60):
|
| 301 |
-
multi.atualizar({"cv2": 4.0, "tend_cv2": 1.0})
|
| 302 |
-
verde &= _ok("β₂ responde a CV² alta (loop negativo)",
|
| 303 |
-
multi.beta2.valor < 1.0, f"β₂ escala = {multi.beta2.valor:.3f}")
|
| 304 |
-
# ε/wd/momentum respondem
|
| 305 |
-
for _ in range(60):
|
| 306 |
-
multi.atualizar({"razao_upd": 3.0, "norma_rel": 1.5,
|
| 307 |
-
"razao_mom": 0.2, "trust": 0.9, "velocidade": 0.01,
|
| 308 |
-
"razao_moe": 0.9, "taxa_som": 0.5,
|
| 309 |
-
"folga_abmo": -0.3, "razao_cresc": 4.0})
|
| 310 |
-
verde &= _ok("ε sobe com ‖Δp‖/‖g‖ alta", multi.eps.valor > 1.0,
|
| 311 |
-
f"{multi.eps.valor:.3f}")
|
| 312 |
-
verde &= _ok("wd sobe com norma relativa > 1", multi.wd.valor > 1.0,
|
| 313 |
-
f"{multi.wd.valor:.3f}")
|
| 314 |
-
verde &= _ok("momentum sobe com razão baixa (Teo 30.6)",
|
| 315 |
-
multi.momentum.valor > 1.0, f"{multi.momentum.valor:.3f}")
|
| 316 |
-
verde &= _ok("PESO_MOE desce com razão > ½ (Teo 30.11)",
|
| 317 |
-
multi.peso_moe.valor < 1.0, f"{multi.peso_moe.valor:.3f}")
|
| 318 |
-
verde &= _ok("PESO_SOM sobe com ativação < 90% (Teo 30.12)",
|
| 319 |
-
multi.peso_som.valor > 1.0, f"{multi.peso_som.valor:.3f}")
|
| 320 |
-
verde &= _ok("margem ABMO desce com folga negativa (Teo 30.13)",
|
| 321 |
-
multi.abmo_margem.valor < 1.0, f"{multi.abmo_margem.valor:.3f}")
|
| 322 |
-
# τ_qk bisseção: contrai e mantém erro ≤ (τmax−τmin)/2^k (Teo 30.7)
|
| 323 |
-
tq = BissecaoTauQK(faixa=(80.0, 120.0), tau_min=20.0, tau_max=240.0,
|
| 324 |
-
tau0=100.0, paciencia=1)
|
| 325 |
-
for lmax in (200.0, 200.0, 200.0): # ℓ_max alto ⟹ τ desce
|
| 326 |
-
tq.registrar_lmax(lmax)
|
| 327 |
-
verde &= _ok("τ_qk desce com ℓ_max > hi", tq.tau < 100.0,
|
| 328 |
-
f"τ = {tq.tau:.1f} (contração 1/2 — Teo 30.7)")
|
| 329 |
-
# PID: canal integral com vazamento limitado (anti-windup)
|
| 330 |
-
ch = ControladorHibrido((0.5, 2.0), b=0.0, c_i=0.05)
|
| 331 |
-
for _ in range(500):
|
| 332 |
-
ch.atualizar(0.0, erro=1.0) # erro constante ⟹ I satura em 1
|
| 333 |
-
verde &= _ok("integral com vazamento SATURA em 1 (anti-windup)",
|
| 334 |
-
abs(ch.I - 1.0) < 1e-9, f"I = {ch.I:.4f}")
|
| 335 |
-
# limites respeitados sempre (Teo 30.1: truncagem garante pertença)
|
| 336 |
-
ch2 = ControladorHibrido((0.5, 2.0), b=0.2, c_i=0.1, c_d=0.1)
|
| 337 |
-
for _ in range(2000):
|
| 338 |
-
ch2.atualizar(1.0, erro=1.0)
|
| 339 |
-
verde &= _ok("θ ∈ [θ_min, θ_max] SEMPRE (Teo 30.1)",
|
| 340 |
-
0.5 - 1e-12 <= ch2.valor <= 2.0 + 1e-12,
|
| 341 |
-
f"θ = {ch2.valor:.4f}")
|
| 342 |
-
return verde
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
def main() -> int:
|
| 346 |
-
ap = argparse.ArgumentParser()
|
| 347 |
-
ap.add_argument("--rapido", action="store_true")
|
| 348 |
-
args = ap.parse_args()
|
| 349 |
-
t0 = time.time()
|
| 350 |
-
print("=" * 72)
|
| 351 |
-
print("VERIFICAÇÃO v17 KHMAMBAJEPA — doc 29 (Teos 29.1–29.14) + doc 30")
|
| 352 |
-
print("=" * 72)
|
| 353 |
-
torch.manual_seed(2026)
|
| 354 |
-
resultados = {"A": bloco_a(), "B": bloco_b(),
|
| 355 |
-
"C": bloco_c(args.rapido), "D": bloco_d(),
|
| 356 |
-
"E": bloco_e(), "F": bloco_f(), "G": bloco_g(),
|
| 357 |
-
"H": bloco_h()}
|
| 358 |
-
print("\n" + "=" * 72)
|
| 359 |
-
for k, v in resultados.items():
|
| 360 |
-
print(f" bloco {k}: {'VERDE' if v else 'VERMELHO'}")
|
| 361 |
-
ok = all(resultados.values())
|
| 362 |
-
print(f"\n{'TUDO VERDE ✓' if ok else 'HÁ FALHAS ✗'}"
|
| 363 |
-
f" ({time.time() - t0:.1f}s)")
|
| 364 |
-
return 0 if ok else 1
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
if __name__ == "__main__":
|
| 368 |
-
sys.exit(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/khtst/acelerado/setup.py
CHANGED
|
@@ -44,17 +44,6 @@ extensoes = [
|
|
| 44 |
extra_link_args=["-fopenmp"],
|
| 45 |
language="c",
|
| 46 |
),
|
| 47 |
-
# v17 — jepa_validator (doc 29, Teos 29.10–29.12): registro/auditoria de
|
| 48 |
-
# variantes JEPA (acumulação C long long), Token Rounding EXATO no bloco
|
| 49 |
-
# de predição (n̂ = τ·⌈n/τ⌉, offsets por prefixo, GEMM bit-exato nas
|
| 50 |
-
# linhas vivas) e AuditoriaMemoriaSonic (statm nível C ~µs; I1–I4).
|
| 51 |
-
Extension(
|
| 52 |
-
"jepa_validator",
|
| 53 |
-
sources=["jepa_validator.pyx"],
|
| 54 |
-
include_dirs=[numpy.get_include()],
|
| 55 |
-
extra_compile_args=["-O3", "-march=native"],
|
| 56 |
-
language="c++",
|
| 57 |
-
),
|
| 58 |
]
|
| 59 |
|
| 60 |
setup(
|
|
|
|
| 44 |
extra_link_args=["-fopenmp"],
|
| 45 |
language="c",
|
| 46 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
]
|
| 48 |
|
| 49 |
setup(
|
src/khtst/aprimoramento/__init__.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Pacote de APRIMORAMENTO KHTST (v17) — módulos da rodada de análise:
|
| 3 |
+
difusão com gradiente vivo, métricas QE+CT com significância, λ_c
|
| 4 |
+
unificado com sinal suavizado, trade-off K com Ĉ estimado e unimodalidade
|
| 5 |
+
provada, JEPA com anti-colapso por dimensão e o CONTROLADOR HÍBRIDO
|
| 6 |
+
(RM+PI+bisseção) com a tabela de sinais da autorregulação estendida.
|
| 7 |
+
|
| 8 |
+
Provas: docs/matematica/29-autorregulacao-hibrida-aprimoramentos.md
|
| 9 |
+
(Teos 29.1–29.16). Suíte: tests/test_khtst_v17.py.
|
| 10 |
+
"""
|
| 11 |
+
from .config import (DifusaoConfig, JEPAConfig, KHTSTConfig,
|
| 12 |
+
LambdaCConfig, QECTConfig, TradeoffKConfig)
|
| 13 |
+
from .controlador_hibrido import ControladorBissecao, ControladorHibrido
|
| 14 |
+
from .autorregulacao_estendida import (AutorreguladorEstendido,
|
| 15 |
+
sinal_razao)
|
| 16 |
+
from .lambda_c_unificado import (AutoAjusteLambdaC, equivalencia_numerica,
|
| 17 |
+
fast_path_step, ref_path_step)
|
| 18 |
+
from .tradeoff_k import (J1, J2, ResultadoK, estimar_C, epsilon_sq,
|
| 19 |
+
k_star_fechado, resolver_K, validar_v15_1)
|
| 20 |
+
from .metricas_qe_ct import (ResultadoQECT, avaliar_ganho,
|
| 21 |
+
consistencia_temporal, erro_quantizacao,
|
| 22 |
+
te_antigo)
|
| 23 |
+
from .difusao_gradiente import (AutoLambdaDiff, DifusaoDDPM, DenoiserMLP,
|
| 24 |
+
treinar_difusao)
|
| 25 |
+
from .jepa import JEPA, Encoder, MLP, hinge_variancia_por_dim
|
| 26 |
+
|
| 27 |
+
__all__ = [
|
| 28 |
+
"DifusaoConfig", "JEPAConfig", "KHTSTConfig", "LambdaCConfig",
|
| 29 |
+
"QECTConfig", "TradeoffKConfig",
|
| 30 |
+
"ControladorBissecao", "ControladorHibrido",
|
| 31 |
+
"AutorreguladorEstendido", "sinal_razao",
|
| 32 |
+
"AutoAjusteLambdaC", "equivalencia_numerica", "fast_path_step",
|
| 33 |
+
"ref_path_step",
|
| 34 |
+
"J1", "J2", "ResultadoK", "estimar_C", "epsilon_sq", "k_star_fechado",
|
| 35 |
+
"resolver_K", "validar_v15_1",
|
| 36 |
+
"ResultadoQECT", "avaliar_ganho", "consistencia_temporal",
|
| 37 |
+
"erro_quantizacao", "te_antigo",
|
| 38 |
+
"AutoLambdaDiff", "DifusaoDDPM", "DenoiserMLP", "treinar_difusao",
|
| 39 |
+
"JEPA", "Encoder", "MLP", "hinge_variancia_por_dim",
|
| 40 |
+
]
|
src/khtst/aprimoramento/autorregulacao_estendida.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""AUTORREGULAÇÃO ESTENDIDA v17 — a tabela de sinais (doc 29 §10, Teo 29.16).
|
| 3 |
+
|
| 4 |
+
Fecha a lacuna diagnosticada na v16: o Autorregulador (Teos 28.5–28.7)
|
| 5 |
+
governava lr, λ_aux e peso MoE com RM puro e UM sinal por parâmetro —
|
| 6 |
+
sem correlação entre métricas, sem memória de longo prazo, sem rastreio
|
| 7 |
+
de setpoint, e SEM cobertura de AdamW (β₁/β₂/ε/wd), Muon (momentum/
|
| 8 |
+
escala/τ_qk), PRS V8 (5 parâmetros), pesos de perda (PESO_MOE,
|
| 9 |
+
PESO_ALINHAMENTO_SOM), ABMO, CIAR e crescimento.
|
| 10 |
+
|
| 11 |
+
ESTE módulo registra CADA parâmetro em um ControladorHibrido (RM + PI,
|
| 12 |
+
Teo 29.14) ou ControladorBissecao (τ_qk, Teo 29.15), com:
|
| 13 |
+
|
| 14 |
+
• NASCIMENTO NEUTRO: o centro de cada controlador é a constante ATUAL
|
| 15 |
+
de produção — com autorreg desligada, o comportamento é bit-a-bit o
|
| 16 |
+
da v16; ligada, cada parâmetro parte do valor comprovado e se move
|
| 17 |
+
dentro de limites SEGUROS (nunca diverge);
|
| 18 |
+
• SETPOINT EXPLÍCITO por parâmetro (o laço PI rastreia o alvo — o RM
|
| 19 |
+
sozinho só converge ao estacionário do campo, que pode ter viés);
|
| 20 |
+
• TELEMETRIA TOTAL: cada valor e cada erro é registrado no
|
| 21 |
+
TelemetryHub (requisito: todos os sinais auditáveis).
|
| 22 |
+
|
| 23 |
+
TABELA DE SINAIS (Teo 29.16 — cada linha é um parâmetro regulável):
|
| 24 |
+
|
| 25 |
+
AdamW β₁ PID varância do gradiente (proxy de curvatura) [0.80, 0.95]
|
| 26 |
+
AdamW β₂ PID deriva relativa do segundo momento [0.90, 0.999]
|
| 27 |
+
AdamW ε RM razão ‖update‖/‖g‖ contra o alvo 1.0 [1e-10, 1e-6]
|
| 28 |
+
AdamW wd PID norma L2 média dos pesos contra 1.0 [0.0, 0.10]
|
| 29 |
+
Muon momentum RM razão ‖momentum‖/‖g‖ contra o alvo 1.0 [0.80, 0.99]
|
| 30 |
+
Muon escala PID razão RMS(update Muon)/RMS(update AdamW) → 1.0 [0.10, 0.40]
|
| 31 |
+
τ_qk BISS banda ℓ_max ∈ [80, 120] (Teo 29.15) [40, 400]
|
| 32 |
+
PRS η_up PID taxa de acerto do trust contra o alvo [0.01, 0.15]
|
| 33 |
+
PRS η_down PID 1 − taxa de acerto (corta mais quando erra) [0.005, 0.10]
|
| 34 |
+
PRS T_ciclo RM velocidade Δperda/passo contra vel_alvo [200, 1200]
|
| 35 |
+
PRS decay_piso RM idem (família de progresso) [0.30, 0.80]
|
| 36 |
+
PRS percentil RM razão de clips contra o alvo 0.10 [0.50, 0.95]
|
| 37 |
+
PESO_MOE RM razão L_moe/L_ce contra o alvo 0.5 (Teo 28.7-ii)[0.005, 0.08]
|
| 38 |
+
PESO_SOM PID taxa de ativação da SOM contra 0.90 [0.01, 0.20]
|
| 39 |
+
ABMO margem RM folga da barreira η ≤ (2−m)/L̂ (Teo 24.9) [0.5, 1.5]×
|
| 40 |
+
CIAR κ PID taxa de aceitação contra o alvo [0.5, 2.0]×
|
| 41 |
+
cresc. expand RM taxa de expansão contra o alvo 0.05 [0.5, 2.0]×
|
| 42 |
+
cresc. prune RM taxa de poda contra o alvo 0.02 [0.5, 2.0]×
|
| 43 |
+
"""
|
| 44 |
+
from __future__ import annotations
|
| 45 |
+
|
| 46 |
+
import math
|
| 47 |
+
from typing import Callable
|
| 48 |
+
|
| 49 |
+
from .controlador_hibrido import ControladorBissecao, ControladorHibrido
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def sinal_razao(x: float, alvo: float) -> float:
|
| 53 |
+
"""Sinal RM normalizado: clip((x−alvo)/max(|alvo|,ε), ±1) — adimensional,
|
| 54 |
+
independente da escala da métrica (regra do projeto: sinais ∈ [−1,1])."""
|
| 55 |
+
denom = max(abs(alvo), 1e-9)
|
| 56 |
+
return max(-1.0, min(1.0, (float(x) - alvo) / denom))
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
class AutorreguladorEstendido:
|
| 60 |
+
"""Tabela de sinais v17 — um controlador híbrido por parâmetro.
|
| 61 |
+
|
| 62 |
+
Uso no treinador (opt-in; nascimento neutro):
|
| 63 |
+
areg = AutorreguladorEstendido(hub=hub)
|
| 64 |
+
valores = areg.registrar({"var_grad": 0.8, "taxa_acerto_trust": 0.7, ...})
|
| 65 |
+
areg.aplicar_em_otimizador(valores, opt)
|
| 66 |
+
areg.aplicar_em_prs(valores, prs)
|
| 67 |
+
"""
|
| 68 |
+
|
| 69 |
+
def __init__(self, cfg: dict | None = None, hub=None,
|
| 70 |
+
a0: float = 0.05, tau_a: float = 400.0, espera: int = 20):
|
| 71 |
+
cfg = cfg or {}
|
| 72 |
+
self.hub = hub
|
| 73 |
+
self.ativo = bool(cfg.get("ativo", False)) # NASCIMENTO NEUTRO
|
| 74 |
+
self.a_cada = int(cfg.get("a_cada", 10))
|
| 75 |
+
self._passo = 0
|
| 76 |
+
self._t_ajuste = 0
|
| 77 |
+
C = self._construir(a0, tau_a, espera)
|
| 78 |
+
self._controladores: dict[str, object] = C
|
| 79 |
+
|
| 80 |
+
# ------------------------------------------------------------------
|
| 81 |
+
def _construir(self, a0: float, tau_a: float, espera: int) -> dict:
|
| 82 |
+
"""Instancia a tabela Teo 29.16 (centros = constantes v16)."""
|
| 83 |
+
def h(centro, limites, b_i=0.0, c_d=0.0, alvo=1.0, passo_max=0.02):
|
| 84 |
+
return ControladorHibrido(centro, limites, a0=a0, tau_a=tau_a,
|
| 85 |
+
passo_max=passo_max, b_i=b_i, c_d=c_d,
|
| 86 |
+
alvo=alvo, espera=espera)
|
| 87 |
+
return {
|
| 88 |
+
# ---- AdamW (grupo `adam`) ----
|
| 89 |
+
"adamw_beta1": h(0.90, (0.80, 0.95), b_i=0.05, alvo=1.0),
|
| 90 |
+
"adamw_beta2": h(0.95, (0.90, 0.999), b_i=0.05, alvo=1.0),
|
| 91 |
+
"adamw_eps": h(1e-8, (1e-10, 1e-6), alvo=1.0, passo_max=0.05),
|
| 92 |
+
"adamw_wd": h(0.01, (1e-4, 0.10), b_i=0.10, alvo=1.0),
|
| 93 |
+
# ---- Muon ----
|
| 94 |
+
"muon_momentum": h(0.95, (0.80, 0.99), alvo=1.0),
|
| 95 |
+
"muon_escala": h(0.20, (0.10, 0.40), b_i=0.05, alvo=1.0),
|
| 96 |
+
"tau_qk": ControladorBissecao(100.0, (80.0, 120.0),
|
| 97 |
+
modo="escala", eta=0.5),
|
| 98 |
+
# ---- PRS V8 ----
|
| 99 |
+
"prs_eta_up": h(0.05, (0.01, 0.15), b_i=0.10, alvo=0.60),
|
| 100 |
+
"prs_eta_down": h(0.02, (0.005, 0.10), b_i=0.10, alvo=0.60),
|
| 101 |
+
"prs_T_ciclo": h(400.0, (200.0, 1200.0), alvo=1.0, passo_max=0.01),
|
| 102 |
+
"prs_decay_piso": h(0.50, (0.30, 0.80), alvo=1.0, passo_max=0.01),
|
| 103 |
+
"prs_percentil": h(0.75, (0.50, 0.95), alvo=0.10, passo_max=0.02),
|
| 104 |
+
# ---- pesos de perda ----
|
| 105 |
+
"peso_moe": h(0.02, (0.005, 0.08), alvo=0.5, passo_max=0.03),
|
| 106 |
+
"peso_som": h(0.05, (0.01, 0.20), b_i=0.10, alvo=0.90),
|
| 107 |
+
# ---- ABMO / CIAR / crescimento (escala ×) ----
|
| 108 |
+
"abmo_margem": h(1.0, (0.5, 1.5), alvo=1.0),
|
| 109 |
+
"ciar_kappa": h(1.0, (0.5, 2.0), b_i=0.05, alvo=0.70),
|
| 110 |
+
"cresc_expand": h(1.0, (0.5, 2.0), alvo=0.05),
|
| 111 |
+
"cresc_prune": h(1.0, (0.5, 2.0), alvo=0.02),
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
# ------------------------------------------------------------------
|
| 115 |
+
# TABELA: parâmetro → (sinal RM, medida PI) a partir do dicionário de
|
| 116 |
+
# telemetria bruta. Cada função é total (default neutro se faltar a
|
| 117 |
+
# métrica — sinal 0 = "não move", medida None = "PI não atua").
|
| 118 |
+
def _tabela_sinais(self) -> dict[str, tuple[Callable, Callable]]:
|
| 119 |
+
def f_sinal(chave, alvo, inverte=False):
|
| 120 |
+
def f(t):
|
| 121 |
+
if chave not in t:
|
| 122 |
+
return 0.0
|
| 123 |
+
s = sinal_razao(t[chave], alvo)
|
| 124 |
+
return -s if inverte else s
|
| 125 |
+
return f
|
| 126 |
+
|
| 127 |
+
def f_medida(chave, alvo):
|
| 128 |
+
def f(t):
|
| 129 |
+
return float(t[chave]) if chave in t else None
|
| 130 |
+
return f
|
| 131 |
+
|
| 132 |
+
return {
|
| 133 |
+
# AdamW β₁ — proxy de curvatura: variância do gradiente padronizada
|
| 134 |
+
# já vem normalizada do produtor (var_grad_norm ∈ [0,∞), alvo 1.0)
|
| 135 |
+
"adamw_beta1": (f_sinal("var_grad_norm", 1.0),
|
| 136 |
+
f_medida("var_grad_norm", 1.0)),
|
| 137 |
+
# AdamW β₂ — deriva do segundo momento (alvo 1.0 = estável);
|
| 138 |
+
# deriva ALTA ⟹ β₂ desce (sinal invertido: deriva alta ⟹ ↓β₂)
|
| 139 |
+
"adamw_beta2": (f_sinal("deriva_seg_momento", 1.0, inverte=True),
|
| 140 |
+
f_medida("deriva_seg_momento", 1.0)),
|
| 141 |
+
# AdamW ε — razão ‖update‖/‖g‖ vs 1.0 (Teo 29.16)
|
| 142 |
+
"adamw_eps": (f_sinal("razao_update_grad", 1.0),
|
| 143 |
+
f_medida("razao_update_grad", 1.0)),
|
| 144 |
+
# AdamW wd — norma L2 média vs 1.0: pesos pesados ⟹ wd sobe
|
| 145 |
+
"adamw_wd": (f_sinal("norma_peso", 1.0),
|
| 146 |
+
f_medida("norma_peso", 1.0)),
|
| 147 |
+
# Muon momentum — ‖momentum‖/‖g‖ vs 1.0
|
| 148 |
+
"muon_momentum": (f_sinal("razao_momentum_grad", 1.0),
|
| 149 |
+
f_medida("razao_momentum_grad", 1.0)),
|
| 150 |
+
# Muon escala — RMS(Muon)/RMS(AdamW) vs 1.0 (Teo 24.11)
|
| 151 |
+
"muon_escala": (f_sinal("razao_rms_mecanismos", 1.0),
|
| 152 |
+
f_medida("razao_rms_mecanismos", 1.0)),
|
| 153 |
+
# τ_qk — controlado por ControladorBissecao (logit_max bruto)
|
| 154 |
+
"tau_qk": (lambda t: 0.0, f_medida("logit_max", 100.0)),
|
| 155 |
+
# PRS η_up — acerto acima do alvo ⟹ sobe mais agressivo
|
| 156 |
+
"prs_eta_up": (f_sinal("taxa_acerto_trust", 0.60),
|
| 157 |
+
f_medida("taxa_acerto_trust", 0.60)),
|
| 158 |
+
# PRS η_down — acerto BAIXO ⟹ corta mais (sinal invertido)
|
| 159 |
+
"prs_eta_down": (f_sinal("taxa_acerto_trust", 0.60, inverte=True),
|
| 160 |
+
f_medida("taxa_acerto_trust", 0.60)),
|
| 161 |
+
# PRS T_ciclo — progresso rápido (Δperda alto) ⟹ ciclo MAIOR
|
| 162 |
+
"prs_T_ciclo": (f_sinal("delta_perda_passo", 0.01),
|
| 163 |
+
f_medida("delta_perda_passo", 0.01)),
|
| 164 |
+
"prs_decay_piso": (f_sinal("delta_perda_passo", 0.01),
|
| 165 |
+
f_medida("delta_perda_passo", 0.01)),
|
| 166 |
+
# PRS percentil — clips acima do alvo 0.10 ⟹ percentil sobe
|
| 167 |
+
"prs_percentil": (f_sinal("razao_clip", 0.10),
|
| 168 |
+
f_medida("razao_clip", 0.10)),
|
| 169 |
+
# PESO_MOE — razão L_moe/L_ce acima de 0.5 ⟹ peso desce
|
| 170 |
+
# (Teo 28.7-ii: CE é a descida primária)
|
| 171 |
+
"peso_moe": (None, None), # tratado abaixo (sinal direto)
|
| 172 |
+
# PESO_SOM — ativação abaixo de 0.90 ⟹ peso sobe
|
| 173 |
+
"peso_som": (f_sinal("ativacao_som", 0.90),
|
| 174 |
+
f_medida("ativacao_som", 0.90)),
|
| 175 |
+
# ABMO — folga da barreira: sinal já normalizado ±1
|
| 176 |
+
"abmo_margem": (f_sinal("margem_abmo_norm", 1.0),
|
| 177 |
+
f_medida("margem_abmo_norm", 1.0)),
|
| 178 |
+
# CIAR κ — aceitação vs alvo
|
| 179 |
+
"ciar_kappa": (f_sinal("taxa_aceitacao_ciar", 0.70),
|
| 180 |
+
f_medida("taxa_aceitacao_ciar", 0.70)),
|
| 181 |
+
# crescimento — expansão/poda vs alvos
|
| 182 |
+
"cresc_expand": (f_sinal("taxa_expansao", 0.05),
|
| 183 |
+
f_medida("taxa_expansao", 0.05)),
|
| 184 |
+
"cresc_prune": (f_sinal("taxa_prune", 0.02),
|
| 185 |
+
f_medida("taxa_prune", 0.02)),
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
# ------------------------------------------------------------------
|
| 189 |
+
def registrar(self, telemetria: dict) -> dict[str, float]:
|
| 190 |
+
"""Um ciclo de ajuste: sinais → controladores → valores novos.
|
| 191 |
+
|
| 192 |
+
`telemetria` pode conter QUALQUER subconjunto das chaves —
|
| 193 |
+
parâmetros sem sinal simplesmente não movem (robustez)."""
|
| 194 |
+
self._passo += 1
|
| 195 |
+
if not self.ativo or (self._passo % self.a_cada) != 0:
|
| 196 |
+
return {k: self._valor(k) for k in self._controladores}
|
| 197 |
+
self._t_ajuste += 1
|
| 198 |
+
tabela = self._tabela_sinais()
|
| 199 |
+
valores: dict[str, float] = {}
|
| 200 |
+
for nome, ctl in self._controladores.items():
|
| 201 |
+
if isinstance(ctl, ControladorBissecao):
|
| 202 |
+
if "logit_max" in telemetria:
|
| 203 |
+
ctl.atualizar(float(telemetria["logit_max"]))
|
| 204 |
+
valores[nome] = ctl.tau
|
| 205 |
+
if self.hub is not None:
|
| 206 |
+
self.hub.atributo(f"autorreg_v17/{nome}", ctl.tau)
|
| 207 |
+
continue
|
| 208 |
+
sinal_fn, medida_fn = tabela[nome]
|
| 209 |
+
if nome == "peso_moe":
|
| 210 |
+
# sinal DIRETO: e = (alvo − razão)/alvo — acima do alvo ⟹ ↓
|
| 211 |
+
if "razao_moe_ce" in telemetria:
|
| 212 |
+
r = float(telemetria["razao_moe_ce"])
|
| 213 |
+
s = max(-1.0, min(1.0, (0.5 - r) / 0.5))
|
| 214 |
+
medida = r
|
| 215 |
+
else:
|
| 216 |
+
s, medida = 0.0, None
|
| 217 |
+
else:
|
| 218 |
+
s = float(sinal_fn(telemetria))
|
| 219 |
+
medida = medida_fn(telemetria)
|
| 220 |
+
ctl.atualizar(s, medida)
|
| 221 |
+
valores[nome] = ctl.valor
|
| 222 |
+
if self.hub is not None:
|
| 223 |
+
self.hub.atributo(f"autorreg_v17/{nome}", ctl.valor)
|
| 224 |
+
if ctl.e_anterior is not None:
|
| 225 |
+
self.hub.atributo(f"autorreg_v17/{nome}__erro",
|
| 226 |
+
ctl.e_anterior)
|
| 227 |
+
return valores
|
| 228 |
+
|
| 229 |
+
def _valor(self, nome: str) -> float:
|
| 230 |
+
ctl = self._controladores[nome]
|
| 231 |
+
return ctl.tau if isinstance(ctl, ControladorBissecao) else ctl.valor
|
| 232 |
+
|
| 233 |
+
# ------------------------------------------------------------------
|
| 234 |
+
# ADAPTADORES de aplicação (escrita segura nos consumos)
|
| 235 |
+
def aplicar_em_otimizador(self, valores: dict, opt) -> list[str]:
|
| 236 |
+
"""Escreve β₁/β₂/ε/wd (grupo AdamW), momentum/escala (Muon) e τ_qk
|
| 237 |
+
nos param_groups. Campos ausentes são ignorados (idempotente)."""
|
| 238 |
+
tocados = []
|
| 239 |
+
for grupo in getattr(opt, "param_groups", []):
|
| 240 |
+
if "adamw_beta1" in valores and "betas" in grupo:
|
| 241 |
+
b1 = max(0.0, min(0.999, valores["adamw_beta1"]))
|
| 242 |
+
b2 = max(b1, min(0.9999, valores.get("adamw_beta2",
|
| 243 |
+
grupo["betas"][1])))
|
| 244 |
+
grupo["betas"] = (b1, b2)
|
| 245 |
+
tocados.append("betas")
|
| 246 |
+
if "adamw_eps" in valores and "eps" in grupo:
|
| 247 |
+
grupo["eps"] = float(max(1e-12, valores["adamw_eps"]))
|
| 248 |
+
tocados.append("eps")
|
| 249 |
+
if "adamw_wd" in valores and "weight_decay" in grupo:
|
| 250 |
+
grupo["weight_decay"] = float(max(0.0, valores["adamw_wd"]))
|
| 251 |
+
tocados.append("weight_decay")
|
| 252 |
+
if "muon_momentum" in valores and "momentum" in grupo:
|
| 253 |
+
grupo["momentum"] = float(max(0.0, min(0.999,
|
| 254 |
+
valores["muon_momentum"])))
|
| 255 |
+
tocados.append("momentum")
|
| 256 |
+
if "muon_escala" in valores and "escala_muon" in grupo:
|
| 257 |
+
grupo["escala_muon"] = float(max(1e-3, valores["muon_escala"]))
|
| 258 |
+
tocados.append("escala_muon")
|
| 259 |
+
if "tau_qk" in valores and grupo.get("tau_qk", None):
|
| 260 |
+
grupo["tau_qk"] = float(valores["tau_qk"])
|
| 261 |
+
tocados.append("tau_qk")
|
| 262 |
+
return sorted(set(tocados))
|
| 263 |
+
|
| 264 |
+
def aplicar_em_prs(self, valores: dict, prs) -> list[str]:
|
| 265 |
+
"""Escreve os 5 parâmetros do PRS V8 dentro dos limites seguros.
|
| 266 |
+
Atributos ausentes no objeto são ignorados (adapter tolerante)."""
|
| 267 |
+
mapa = {"prs_eta_up": "eta_up", "prs_eta_down": "eta_down",
|
| 268 |
+
"prs_T_ciclo": "T_ciclo", "prs_decay_piso": "decay_piso",
|
| 269 |
+
"prs_percentil": "percentil"}
|
| 270 |
+
tocados = []
|
| 271 |
+
for chave, attr in mapa.items():
|
| 272 |
+
if chave in valores and hasattr(prs, attr):
|
| 273 |
+
v = float(valores[chave])
|
| 274 |
+
if attr == "T_ciclo":
|
| 275 |
+
v = max(1, int(round(v)))
|
| 276 |
+
setattr(prs, attr, v)
|
| 277 |
+
tocados.append(attr)
|
| 278 |
+
return sorted(set(tocados))
|
| 279 |
+
|
| 280 |
+
def telemetria(self) -> dict:
|
| 281 |
+
out = {}
|
| 282 |
+
for nome, ctl in self._controladores.items():
|
| 283 |
+
v = ctl.tau if isinstance(ctl, ControladorBissecao) else ctl.valor
|
| 284 |
+
out[f"autorreg_v17/{nome}"] = v
|
| 285 |
+
return out
|
src/khtst/aprimoramento/config.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Configuração do pacote de APRIMORAMENTO KHTST (v17) — fonte única das
|
| 3 |
+
constantes deste pacote (regra do projeto: nenhum número solto em módulos).
|
| 4 |
+
|
| 5 |
+
Relação com khtst.config (produção): ESTE config é auto-contido e governa
|
| 6 |
+
apenas o pacote `aprimoramento`. Os defaults respeitam a convenção de
|
| 7 |
+
NASCIMENTO NEUTRO: com todos os flags em default, o comportamento é
|
| 8 |
+
idêntico ao dos rascunhos de referência — cada aprimoramento novo entra
|
| 9 |
+
com um campo próprio que pode ser desligado individualmente.
|
| 10 |
+
|
| 11 |
+
CORREÇÕES de integração sobre o rascunho (defeitos D11/D12/D14 do doc 29):
|
| 12 |
+
• JEPAConfig.peso_var — o peso 0.01 do hinge de variância era
|
| 13 |
+
HARD-CODED no forward; agora é campo.
|
| 14 |
+
• JEPAConfig.ema_cosseno — agenda de momentum EMA (BYOL) opt-in.
|
| 15 |
+
• QECTConfig.normalizar — existia no rascunho e NUNCA era lido
|
| 16 |
+
(campo morto); agora governa a normalização
|
| 17 |
+
do QE (invariância de escala, Teo 29.4).
|
| 18 |
+
• QECTConfig.alpha/n_min — significância estatística do "ganho real"
|
| 19 |
+
(Teo 29.5 — Hoeffding) no lugar da conjunção
|
| 20 |
+
de limiares fixos.
|
| 21 |
+
• DifusaoConfig.eta_lambda — existia e NUNCA era lido; agora alimenta
|
| 22 |
+
o AutoLambdaDiff (Teo 29.2).
|
| 23 |
+
• DifusaoConfig.rho_ancora — âncora quadrática que dá ÓTIMO INTERIOR
|
| 24 |
+
provado para λ_diff (Teo 29.2-iii).
|
| 25 |
+
• LambdaCConfig.modo/tau_eta— sinal suavizado (correção do defeito D6:
|
| 26 |
+
a média da janela era computada e jogada
|
| 27 |
+
fora) + agenda RM opcional (Teo 29.7-ii).
|
| 28 |
+
• TradeoffKConfig.estimar_C — constante de Zador estimada por OLS
|
| 29 |
+
log-log (Teo 29.8) em vez de C=1 fixo.
|
| 30 |
+
"""
|
| 31 |
+
from __future__ import annotations
|
| 32 |
+
|
| 33 |
+
from dataclasses import dataclass, field
|
| 34 |
+
from typing import Literal
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
@dataclass
|
| 38 |
+
class JEPAConfig:
|
| 39 |
+
dim: int = 256
|
| 40 |
+
pred_hidden: int = 512
|
| 41 |
+
ema_momentum: float = 0.996
|
| 42 |
+
ema_cosseno: bool = False # Teo 29.12: agenda cosseno BYOL (opt-in)
|
| 43 |
+
lambda_jepa: float = 0.5 # peso do alinhamento (ANTES: campo morto)
|
| 44 |
+
peso_var: float = 0.01 # peso do hinge de variância (ANTES: fixo)
|
| 45 |
+
vicreg_lambda: float = 0.0 # >0 ativa o kernel Cython VICReg (cov)
|
| 46 |
+
vicreg_mu: float = 25.0
|
| 47 |
+
vicreg_gamma: float = 1.0
|
| 48 |
+
use_sg: bool = True # stop-gradient no alvo (sempre recomendado)
|
| 49 |
+
normalize: bool = True # L2-normaliza antes do MSE
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
@dataclass
|
| 53 |
+
class TradeoffKConfig:
|
| 54 |
+
d: int = 512 # dimensão do codebook
|
| 55 |
+
n: int = 100_000 # amostras
|
| 56 |
+
lambda_c: float = 0.5
|
| 57 |
+
K_grid: tuple = (16, 32, 64, 128, 256, 512)
|
| 58 |
+
tol_rel: float = 0.05
|
| 59 |
+
metodo: Literal["rd", "asymp", "grid", "auto"] = "auto"
|
| 60 |
+
estimar_C: bool = True # Teo 29.8: Ĉ por OLS log-log (default ON)
|
| 61 |
+
C_prior: float = 1.0 # prior de shrinkage para Ĉ (Teo 29.8-ii)
|
| 62 |
+
kappa_prior: int = 8 # peso do prior (n_C + κ — bias-variance)
|
| 63 |
+
bits_por_param: float = 16.0
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
@dataclass
|
| 67 |
+
class LambdaCConfig:
|
| 68 |
+
eta: float = 1e-3
|
| 69 |
+
lambda_c_min: float = 0.01
|
| 70 |
+
lambda_c_max: float = 0.99
|
| 71 |
+
janela: int = 100 # passos da média móvel do sinal (D6)
|
| 72 |
+
modo: Literal["alvo", "reversao"] = "alvo"
|
| 73 |
+
# alvo : delta = ε̄² − ε²_alvo (rastreio de um alvo fixo)
|
| 74 |
+
# reversao : delta = ε̄² − média_janela (reversão à média da janela)
|
| 75 |
+
eta_agendado: bool = False # Teo 29.7-ii: η_t = η₀/(1+t/τ) — RM q.c.
|
| 76 |
+
tau_eta: float = 400.0
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
@dataclass
|
| 80 |
+
class QECTConfig:
|
| 81 |
+
eps_qe: float = 1e-3
|
| 82 |
+
eps_ct: float = 1e-3
|
| 83 |
+
normalizar: bool = True # AGORA USADO (D14): QE relativo a ‖x‖²
|
| 84 |
+
alpha: float = 0.05 # nível do teste unilateral (Teo 29.5)
|
| 85 |
+
n_min: int = 32 # amostras mínimas p/ declarar ganho real
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
@dataclass
|
| 89 |
+
class DifusaoConfig:
|
| 90 |
+
T: int = 1000
|
| 91 |
+
beta_start: float = 1e-4
|
| 92 |
+
beta_end: float = 0.02
|
| 93 |
+
lambda_diff: float = 0.1
|
| 94 |
+
eta_lambda: float = 0.05 # AGORA USADO (D14): passo do EG de λ_diff
|
| 95 |
+
rho_ancora: float = 1.0 # Teo 29.2-iii: âncora ρ(λ−λ₀)² (ótimo
|
| 96 |
+
# interior provado; 0 desliga a âncora)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@dataclass
|
| 100 |
+
class KHTSTConfig:
|
| 101 |
+
"""Raiz do pacote — igual ao rascunho de referência + campos novos."""
|
| 102 |
+
jepa: JEPAConfig = field(default_factory=JEPAConfig)
|
| 103 |
+
k: TradeoffKConfig = field(default_factory=TradeoffKConfig)
|
| 104 |
+
lam: LambdaCConfig = field(default_factory=LambdaCConfig)
|
| 105 |
+
qect: QECTConfig = field(default_factory=QECTConfig)
|
| 106 |
+
diff: DifusaoConfig = field(default_factory=DifusaoConfig)
|
| 107 |
+
seed: int = 42
|
src/khtst/aprimoramento/controlador_hibrido.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""CONTROLADOR HÍBRIDO v17 — recursão unificada de autorregulação
|
| 3 |
+
(doc 29 §§2 e 10; Teoremas 29.14–29.16).
|
| 4 |
+
|
| 5 |
+
Recursão ÚNICA que governa todo parâmetro regulável θ (a mesma para os
|
| 6 |
+
~20 parâmetros da tabela de sinais — AdamW, Muon, PRS V8, pesos de perda,
|
| 7 |
+
ABMO, CIAR, crescimento):
|
| 8 |
+
|
| 9 |
+
u_{t+1} = Π_[u_min,u_max] ( u_t + a_t·s_t + b·e_t + c·Δe_t ),
|
| 10 |
+
θ_t = θ₀ · exp(u_t), a_t = a₀/(1 + t/τ_a),
|
| 11 |
+
|
| 12 |
+
• a_t·s_t — termo ROBBINS–MONRO (aprendizado lento, ruído-tolerante).
|
| 13 |
+
Agenda a_t = a₀/(1+t/τ_a) satisfaz Σa_t = ∞ e Σa_t² < ∞ (Teo 28.5
|
| 14 |
+
reutilizado) — convergência q.c. ao ponto estacionário do campo.
|
| 15 |
+
• b·e_t — termo INTEGRAL (PI): e_t = erro normalizado ao alvo.
|
| 16 |
+
Empurra θ para o ALVO declarado (rastreio de setpoint) — corrige
|
| 17 |
+
viés de regime que o sinal RM demoraria a integrar.
|
| 18 |
+
• c·Δe_t — termo DERIVATIVO: Δe_t = e_t − e_{t−1}.
|
| 19 |
+
|
| 20 |
+
DUAS PROVAS QUE JUSTIFICAM A FORMA (Teo 29.14):
|
| 21 |
+
(i) TELESCOPING do D-termo: Σ_{t≤T} c·Δe_t = c·(e_T − e_0) — a
|
| 22 |
+
contribuição CUMULATIVA do termo derivativo é limitada por
|
| 23 |
+
2c·sup|e| para TODO T, independentemente do horizonte. O D-termo
|
| 24 |
+
NUNCA desestabiliza a recursão (contrário do temor clássico).
|
| 25 |
+
(ii) DUAS ESCALAS (Borkar, Teo 28.6 generalizado): com a_t → 0
|
| 26 |
+
(escala LENTA) e ganhos b, c fixos (escala RÁPIDA), a dinâmica
|
| 27 |
+
separa: o laço PI rastreia o setpoint em tempo O(1) e o RM
|
| 28 |
+
converge sobre o equilíbrio já estabilizado. O erro estacionário
|
| 29 |
+
do laço PI com ganho b é |e_∞| = 0 para planta estática de
|
| 30 |
+
primeiro ordem com ganho finito (integral pura zera erro de
|
| 31 |
+
regime — argumento padrão de controle); o anti-windup (projeção +
|
| 32 |
+
congelamento do I fora da região segura) garante que o I-termo
|
| 33 |
+
não dispara além dos limites (Provar: u_t ∈ [u_min,u_max] ∀t por
|
| 34 |
+
indução — a projeção fecha a indução).
|
| 35 |
+
|
| 36 |
+
SEPARAÇÃO HONESTA: o termo RM sozinho (v16) converge ao estacionário
|
| 37 |
+
do CAMPO DE SINAIS, que pode ter viés de regime; o híbrido adiciona
|
| 38 |
+
rastreio de setpoint EXPLÍCITO. Quem define o setpoint é a tabela de
|
| 39 |
+
sinais (autorregulacao_estendida.py).
|
| 40 |
+
"""
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
import math
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class ControladorHibrido:
|
| 47 |
+
"""θ_t = θ₀·exp(u_t) com recursão mista RM + PI projetada.
|
| 48 |
+
|
| 49 |
+
Args:
|
| 50 |
+
centro: θ₀ — valor de NASCIMENTO NEUTRO (u=0 ⟹ θ=θ₀; todas as
|
| 51 |
+
constantes atuais de produção são os centros da tabela).
|
| 52 |
+
limites: (θ_min, θ_max) ABSOLUTOS — segurança estrutural.
|
| 53 |
+
a0, tau_a: agenda RM a_t = a0/(1+t/τ_a) (Σa=∞, Σa²<∞).
|
| 54 |
+
passo_max: |Δu| máximo por passo (segurança multiplicativa).
|
| 55 |
+
b_i, c_d: ganhos integral e derivativo (0 = RM puro, v16).
|
| 56 |
+
alvo: setpoint do erro (se medida for passada).
|
| 57 |
+
escala_e: divisor para normalizar o erro (default: |alvo|).
|
| 58 |
+
espera: passos de aquecimento antes do 1º ajuste (Teo 28.5-ii).
|
| 59 |
+
"""
|
| 60 |
+
|
| 61 |
+
def __init__(self, centro: float, limites: tuple[float, float],
|
| 62 |
+
a0: float = 0.05, tau_a: float = 400.0,
|
| 63 |
+
passo_max: float = 0.05, b_i: float = 0.0, c_d: float = 0.0,
|
| 64 |
+
alvo: float = 1.0, escala_e: float | None = None,
|
| 65 |
+
espera: int = 0):
|
| 66 |
+
assert limites[0] <= centro <= limites[1], "centro fora dos limites"
|
| 67 |
+
self.centro = float(centro)
|
| 68 |
+
self.limites = (float(limites[0]), float(limites[1]))
|
| 69 |
+
self.a0 = float(a0)
|
| 70 |
+
self.tau_a = float(tau_a)
|
| 71 |
+
self.passo_max = float(passo_max)
|
| 72 |
+
self.b_i = float(b_i)
|
| 73 |
+
self.c_d = float(c_d)
|
| 74 |
+
self.alvo = float(alvo)
|
| 75 |
+
self.escala_e = float(escala_e) if escala_e else max(abs(alvo), 1e-9)
|
| 76 |
+
self.espera = int(espera)
|
| 77 |
+
self.t = 0
|
| 78 |
+
self.u = 0.0
|
| 79 |
+
self.e_anterior: float | None = None
|
| 80 |
+
self.i_acum = 0.0 # anti-windup: I explícito e limitado
|
| 81 |
+
|
| 82 |
+
# ------------------------------------------------------------------
|
| 83 |
+
def erro(self, medida: float) -> float:
|
| 84 |
+
"""e_t = (alvo − medida)/escala, clipado a ±2 (robustez a outliers)."""
|
| 85 |
+
e = (self.alvo - float(medida)) / self.escala_e
|
| 86 |
+
return max(-2.0, min(2.0, e))
|
| 87 |
+
|
| 88 |
+
def atualizar(self, sinal_rm: float, medida: float | None = None) -> float:
|
| 89 |
+
"""Um passo da recursão híbrida (EXATAMENTE a forma do doc 29):
|
| 90 |
+
|
| 91 |
+
du = a_t·s_t + b·e_t + c·Δe_t (POR PASSO — sem dupla
|
| 92 |
+
integração: o I é o próprio b·e_t per-step; Σb·e_t é o
|
| 93 |
+
integral implícito da recursão, não um termo extra)
|
| 94 |
+
|
| 95 |
+
Retorna θ_t. sinal_rm ∈ [−1,1] (positivo ↑ θ). `medida` ativa o
|
| 96 |
+
laço PI quando dado. Anti-windup: o termo b·e_t NÃO integra
|
| 97 |
+
quando u está colado na parede NA DIREÇÃO do erro (empurrar
|
| 98 |
+
além da projeção seria enrolar o integral)."""
|
| 99 |
+
sinal_rm = max(-1.0, min(1.0, float(sinal_rm)))
|
| 100 |
+
self.t += 1
|
| 101 |
+
if self.t <= self.espera:
|
| 102 |
+
return self.valor
|
| 103 |
+
a_t = self.a0 / (1.0 + self.t / self.tau_a)
|
| 104 |
+
du = a_t * sinal_rm
|
| 105 |
+
|
| 106 |
+
if medida is not None and (self.b_i != 0.0 or self.c_d != 0.0):
|
| 107 |
+
e = self.erro(medida)
|
| 108 |
+
de = 0.0 if self.e_anterior is None else (e - self.e_anterior)
|
| 109 |
+
self.e_anterior = e
|
| 110 |
+
u_max, u_min = self._u_max(), self._u_min()
|
| 111 |
+
# anti-windup direcional: integra só se empurra PARA DENTRO
|
| 112 |
+
pode_integrar = (e > 0 and self.u > u_min + 1e-12) or \
|
| 113 |
+
(e < 0 and self.u < u_max - 1e-12) or e == 0.0
|
| 114 |
+
if pode_integrar:
|
| 115 |
+
du += self.b_i * e
|
| 116 |
+
self.i_acum += self.b_i * e # telemetria do integral
|
| 117 |
+
i_max = 2.0 * abs(self.b_i) + 1e-12
|
| 118 |
+
self.i_acum = max(-i_max, min(i_max, self.i_acum))
|
| 119 |
+
du += self.c_d * de
|
| 120 |
+
elif medida is not None:
|
| 121 |
+
# sem ganhos PI: apenas registra o erro para telemetria
|
| 122 |
+
self.e_anterior = self.erro(medida)
|
| 123 |
+
|
| 124 |
+
du = max(-self.passo_max, min(self.passo_max, du))
|
| 125 |
+
self.u += du
|
| 126 |
+
self.u = max(self._u_min(), min(self._u_max(), self.u))
|
| 127 |
+
return self.valor
|
| 128 |
+
|
| 129 |
+
def _u_min(self) -> float:
|
| 130 |
+
return math.log(self.limites[0] / self.centro)
|
| 131 |
+
|
| 132 |
+
def _u_max(self) -> float:
|
| 133 |
+
return math.log(self.limites[1] / self.centro)
|
| 134 |
+
|
| 135 |
+
@property
|
| 136 |
+
def valor(self) -> float:
|
| 137 |
+
v = self.centro * math.exp(self.u)
|
| 138 |
+
# clamp final: exp(log(b)) arredonda a b+ε — a permanência no
|
| 139 |
+
# conjunto seguro é EXATA (Teo 29.14-ii sem épsilon de flutuante)
|
| 140 |
+
return min(max(v, self.limites[0]), self.limites[1])
|
| 141 |
+
|
| 142 |
+
def telemetria(self) -> dict:
|
| 143 |
+
return {"valor": self.valor, "u": self.u, "t": self.t,
|
| 144 |
+
"e": self.e_anterior, "i": self.i_acum}
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
class ControladorBissecao:
|
| 148 |
+
"""τ_qk por bisseção com banda-alvo (Teo 29.15).
|
| 149 |
+
|
| 150 |
+
Objetivo do usuário: manter o logit máximo ℓ_max na banda [lo, hi]
|
| 151 |
+
ajustando τ. Como o logit é LINEAR na escala de W_q (Teo 24.7 —
|
| 152 |
+
ℓ(γW) = γ·ℓ(W)), a correção multiplicativa exata é
|
| 153 |
+
τ ← τ·ℓ_alvo/ℓ_medida; com amortecimento η a convergência é
|
| 154 |
+
GEOMÉTRICA (razão |1−η| — mais forte que bisseção). O modo
|
| 155 |
+
"bissecao" puro mantém o colchete [τ_lo, τ_hi] e contrai pela
|
| 156 |
+
metade — erro ≤ (τ_max−τ_min)/2^k (forma do rascunho, mantida).
|
| 157 |
+
"""
|
| 158 |
+
|
| 159 |
+
def __init__(self, tau_inicial: float = 100.0,
|
| 160 |
+
banda: tuple[float, float] = (80.0, 120.0),
|
| 161 |
+
modo: str = "escala", eta: float = 0.5,
|
| 162 |
+
tau_limites: tuple[float, float] = (40.0, 400.0)):
|
| 163 |
+
self.tau = float(tau_inicial)
|
| 164 |
+
self.banda = (float(banda[0]), float(banda[1]))
|
| 165 |
+
self.modo = modo
|
| 166 |
+
self.eta = float(eta)
|
| 167 |
+
self.limites = (float(tau_limites[0]), float(tau_limites[1]))
|
| 168 |
+
# colchete do modo bisseção: [já-seguro, já-inseguro]
|
| 169 |
+
self._colchete = (self.limites[0], self.limites[1])
|
| 170 |
+
self.k = 0
|
| 171 |
+
self.historico: list[float] = []
|
| 172 |
+
|
| 173 |
+
def atualizar(self, logit_max: float) -> float:
|
| 174 |
+
"""Um passo: recebe ℓ_max medido, devolve o novo τ."""
|
| 175 |
+
lo, hi = self.banda
|
| 176 |
+
alvo = 0.5 * (lo + hi)
|
| 177 |
+
l = max(float(logit_max), 1e-9)
|
| 178 |
+
if self.modo == "escala":
|
| 179 |
+
# correção exata amortecida (Teo 29.15-i): ℓ linear em τ ⟹
|
| 180 |
+
# a razão^η leva ao ponto fixo; η=1 corrige em 1 passo
|
| 181 |
+
razao = alvo / l
|
| 182 |
+
self.tau *= razao ** self.eta
|
| 183 |
+
else:
|
| 184 |
+
# bisseção honesta no colchete (semântica PÓS-CLIP — Teo 24.7:
|
| 185 |
+
# ℓ_observado = min(ℓ_natural, τ)):
|
| 186 |
+
# ℓ > hi ⟹ τ ≥ ℓ > hi ⟹ τ ALTO demais ⟹ τ* está ABAIXO;
|
| 187 |
+
# ℓ < lo ⟹ τ < lo (clip nem atuou nessa faixa) ⟹ τ* está ACIMA.
|
| 188 |
+
t_lo, t_hi = self._colchete
|
| 189 |
+
if l > hi:
|
| 190 |
+
t_hi = min(t_hi, self.tau)
|
| 191 |
+
elif l < lo:
|
| 192 |
+
t_lo = max(t_lo, self.tau)
|
| 193 |
+
else:
|
| 194 |
+
# dentro da banda: encolhe o colchete em torno de τ
|
| 195 |
+
t_lo, t_hi = max(t_lo, self.tau * 0.5), min(t_hi, self.tau * 2.0)
|
| 196 |
+
self._colchete = (max(t_lo, self.limites[0]),
|
| 197 |
+
min(t_hi, self.limites[1]))
|
| 198 |
+
self.k += 1
|
| 199 |
+
self.tau = math.sqrt(self._colchete[0] * self._colchete[1])
|
| 200 |
+
self.tau = max(self.limites[0], min(self.limites[1], self.tau))
|
| 201 |
+
self.historico.append(self.tau)
|
| 202 |
+
if len(self.historico) > 512:
|
| 203 |
+
self.historico = self.historico[-256:]
|
| 204 |
+
return self.tau
|
| 205 |
+
|
| 206 |
+
def erro_colchete(self) -> float:
|
| 207 |
+
"""Erro residual do colchete: ≤ (τ_max−τ_min)/2^k (Teo 29.15-ii)."""
|
| 208 |
+
return (self._colchete[1] - self._colchete[0]) / (2 ** max(1, self.k))
|
src/khtst/aprimoramento/difusao_gradiente.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Difusão com gradiente — v17 refatorada (doc 29 §3).
|
| 3 |
+
|
| 4 |
+
DDPM padrão com DUAS correções estruturais sobre o rascunho (defeitos
|
| 5 |
+
D1/D2 do doc 29) e uma prova nova:
|
| 6 |
+
|
| 7 |
+
D1 (CÓDIGO MORTO — defeito real): no rascunho, `lambda_diff` era um
|
| 8 |
+
nn.Parameter com requires_grad=False, `AutoLambdaDiff.step` NUNCA era
|
| 9 |
+
chamado por nenhum caminho, e `treinar_difusao` nem sequer usava
|
| 10 |
+
λ_diff na perda. O "autoajuste por gradiente sobre validação"
|
| 11 |
+
anunciado no docstring era ficção tripla. Aqui:
|
| 12 |
+
(a) a perda ponderada é L(λ) = λ·L_diff + ρ·(λ−λ₀)² — o hiper-
|
| 13 |
+
gradiente é EXATO por ser L AFIM em λ: ∂L/∂λ = L_diff + 2ρ(λ−λ₀)
|
| 14 |
+
(Teo 29.2-i: zero erro de estimação, sem diferenças finitas);
|
| 15 |
+
(b) com ρ>0 (âncora), L(λ) é ESTRITAMENTE CONVEXA em λ com ótimo
|
| 16 |
+
interior FECHADO: λ* = λ₀ − L_diff/(2ρ), clipado a [λmin,λmax]
|
| 17 |
+
(Teo 29.2-iii). Sem âncora, L é afim e o ótimo está SEMPRE na
|
| 18 |
+
borda — o EG empurraria λ para o limite e ficaria lá (a âncora
|
| 19 |
+
é o que torna o autoajuste não-trivial);
|
| 20 |
+
(c) a atualização multiplicativa λ ← λ·exp(−η·g) é descida de
|
| 21 |
+
gradiente EXPLICITEIRA (mirror descent com potencial entropia):
|
| 22 |
+
regret ≤ η·G²T/2 + ln(λmax/λmin)/η, optimizado em η=Θ(T^{−1/2})
|
| 23 |
+
⟹ regret O(√T) — Teo 29.2-ii (Cesa-Bianchi & Lugosi, Cap. 2,
|
| 24 |
+
rederivado no doc 29 para o intervalo clipado).
|
| 25 |
+
|
| 26 |
+
D2 (Polyak ausente): o rascunho amostra a rede crua. Aqui há EMA de
|
| 27 |
+
pesos opcional para amostragem/avaliação — Teo 29.3 (Polyak/Jensen):
|
| 28 |
+
para L convexa em θ, L(θ̄_T) ≤ (1/T)ΣL(θ_t) — a média nunca é pior
|
| 29 |
+
que a média das perdas e remove o ruído de alta frequência do
|
| 30 |
+
caminho SGD (variância do estimador reduzida pelo fator 1/(1−m)
|
| 31 |
+
do EMA; ver doc 29 §3.3).
|
| 32 |
+
|
| 33 |
+
Corretude do núcleo DDPM (reprovada por completude, Teo 29.1):
|
| 34 |
+
q(x_t|x₀) = N(√ᾱ_t·x₀, (1−ᾱ_t)·I) por indução sobre ᾱ_t = ∏_{s≤t}α_s
|
| 35 |
+
(Ho et al. 2020, Lemma 1 — a perda ε é o limite variacional superior
|
| 36 |
+
reponderado; rederivação no doc 29 §3.1). O amostrador inverte a
|
| 37 |
+
média a posteriori q(x_{t−1}|x_t,x₀) com σ_t = √β_t.
|
| 38 |
+
"""
|
| 39 |
+
from __future__ import annotations
|
| 40 |
+
|
| 41 |
+
import math
|
| 42 |
+
from dataclasses import dataclass
|
| 43 |
+
|
| 44 |
+
import torch
|
| 45 |
+
import torch.nn as nn
|
| 46 |
+
import torch.nn.functional as F
|
| 47 |
+
|
| 48 |
+
from .config import DifusaoConfig
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class DenoiserMLP(nn.Module):
|
| 52 |
+
def __init__(self, dim: int, hidden: int = 512):
|
| 53 |
+
super().__init__()
|
| 54 |
+
self.t_proj = nn.Sequential(nn.Linear(1, hidden), nn.GELU(),
|
| 55 |
+
nn.Linear(hidden, hidden))
|
| 56 |
+
self.net = nn.Sequential(
|
| 57 |
+
nn.Linear(dim + hidden, hidden), nn.GELU(),
|
| 58 |
+
nn.Linear(hidden, hidden), nn.GELU(),
|
| 59 |
+
nn.Linear(hidden, dim),
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
def forward(self, x_t, t):
|
| 63 |
+
t_norm = t.float().unsqueeze(-1) / 1000.0
|
| 64 |
+
h_t = self.t_proj(t_norm)
|
| 65 |
+
return self.net(torch.cat([x_t, h_t], dim=-1))
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
class DifusaoDDPM(nn.Module):
|
| 69 |
+
def __init__(self, dim: int, cfg: DifusaoConfig):
|
| 70 |
+
super().__init__()
|
| 71 |
+
self.cfg = cfg
|
| 72 |
+
self.net = DenoiserMLP(dim)
|
| 73 |
+
betas = torch.linspace(cfg.beta_start, cfg.beta_end, cfg.T)
|
| 74 |
+
alphas = 1.0 - betas
|
| 75 |
+
alpha_bar = torch.cumprod(alphas, dim=0)
|
| 76 |
+
self.register_buffer("betas", betas)
|
| 77 |
+
self.register_buffer("alphas", alphas)
|
| 78 |
+
self.register_buffer("alpha_bar", alpha_bar)
|
| 79 |
+
# D1 corrigido: λ_diff é um TENSOR PLANO governado pelo controlador
|
| 80 |
+
# (não parâmetro — autograd não devetocá-lo; o hipergradiente é
|
| 81 |
+
# EXATO e analítico: ∂L/∂λ = L_diff + 2ρ(λ−λ₀), Teo 29.2-i)
|
| 82 |
+
self.lambda_diff = torch.tensor(float(cfg.lambda_diff))
|
| 83 |
+
self.rho_ancora = float(cfg.rho_ancora)
|
| 84 |
+
self.lambda0 = float(cfg.lambda_diff)
|
| 85 |
+
# D2: EMA de pesos (Polyak) — nascimento neutro (default off)
|
| 86 |
+
self._ema: dict[str, torch.Tensor] | None = None
|
| 87 |
+
|
| 88 |
+
# -------------------------------------------------------------- núcleo
|
| 89 |
+
def q_sample(self, x0, t, noise=None):
|
| 90 |
+
if noise is None:
|
| 91 |
+
noise = torch.randn_like(x0)
|
| 92 |
+
ab = self.alpha_bar[t].view(-1, 1)
|
| 93 |
+
return ab.sqrt() * x0 + (1 - ab).sqrt() * noise, noise
|
| 94 |
+
|
| 95 |
+
def loss(self, x0: torch.Tensor) -> torch.Tensor:
|
| 96 |
+
"""L_diff = E ‖ε − ε_θ(x_t, t)‖² (Teo 29.1)."""
|
| 97 |
+
B = x0.shape[0]
|
| 98 |
+
t = torch.randint(0, self.cfg.T, (B,), device=x0.device)
|
| 99 |
+
x_t, noise = self.q_sample(x0, t)
|
| 100 |
+
pred = self.net(x_t, t)
|
| 101 |
+
return F.mse_loss(pred, noise)
|
| 102 |
+
|
| 103 |
+
def loss_ponderada(self, x0: torch.Tensor) -> tuple[torch.Tensor, dict]:
|
| 104 |
+
"""L(λ) = λ·L_diff + ρ·(λ−λ₀)² — AFIM + âncora em λ (Teo 29.2).
|
| 105 |
+
|
| 106 |
+
Devolve (perda escalável, telemetria com o hipergradiente EXATO).
|
| 107 |
+
O gradiente flui para a REDE por λ·L_diff e para λ pelo ramo da
|
| 108 |
+
âncora (implementado como tensor com requires_grad no caminho)."""
|
| 109 |
+
lam = torch.tensor(float(self.lambda_diff), requires_grad=True)
|
| 110 |
+
l_diff = self.loss(x0)
|
| 111 |
+
l_total = lam * l_diff
|
| 112 |
+
if self.rho_ancora > 0:
|
| 113 |
+
l_total = l_total + self.rho_ancora * (lam - self.lambda0) ** 2
|
| 114 |
+
# hipergradiente EXATO (sem autograd no λ — forma fechada):
|
| 115 |
+
g = float(l_diff.detach()) + 2.0 * self.rho_ancora \
|
| 116 |
+
* (float(lam.detach()) - self.lambda0)
|
| 117 |
+
return l_total, {"lambda_diff": float(lam.detach()),
|
| 118 |
+
"hipergradiente": g,
|
| 119 |
+
"perda_difusao": float(l_diff.detach())}
|
| 120 |
+
|
| 121 |
+
@torch.no_grad()
|
| 122 |
+
def sample(self, shape, device="cpu"):
|
| 123 |
+
x = torch.randn(shape, device=device)
|
| 124 |
+
for t in reversed(range(self.cfg.T)):
|
| 125 |
+
tt = torch.full((shape[0],), t, device=device, dtype=torch.long)
|
| 126 |
+
eps = self.net(x, tt)
|
| 127 |
+
a, ab = self.alphas[t], self.alpha_bar[t]
|
| 128 |
+
x = (x - (1 - a) / (1 - ab).sqrt() * eps) / a.sqrt()
|
| 129 |
+
if t > 0:
|
| 130 |
+
x = x + self.betas[t].sqrt() * torch.randn_like(x)
|
| 131 |
+
return x
|
| 132 |
+
|
| 133 |
+
# ------------------------------------------------ D2: EMA (Polyak) ----
|
| 134 |
+
@torch.no_grad()
|
| 135 |
+
def ema_atualizar(self, m: float = 0.999) -> float:
|
| 136 |
+
"""EMA dos pesos do denoiser (Teo 29.3 — Polyak)."""
|
| 137 |
+
if self._ema is None:
|
| 138 |
+
self._ema = {k: v.detach().clone()
|
| 139 |
+
for k, v in self.net.state_dict().items()}
|
| 140 |
+
return m
|
| 141 |
+
for k, v in self.net.state_dict().items():
|
| 142 |
+
if v.dtype.is_floating_point:
|
| 143 |
+
self._ema[k].mul_(m).add_(v.detach(), alpha=1.0 - m)
|
| 144 |
+
else:
|
| 145 |
+
self._ema[k].copy_(v)
|
| 146 |
+
return m
|
| 147 |
+
|
| 148 |
+
@torch.no_grad()
|
| 149 |
+
def carregar_ema(self) -> bool:
|
| 150 |
+
"""Promove os pesos EMA a pesos correntes (avaliação/amostragem)."""
|
| 151 |
+
if not self._ema:
|
| 152 |
+
return False
|
| 153 |
+
self.net.load_state_dict(self._ema)
|
| 154 |
+
return True
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
# ------------------------- autoajuste de λ_diff (D1 VIVO) -----------------
|
| 158 |
+
|
| 159 |
+
@dataclass
|
| 160 |
+
class AutoLambdaDiff:
|
| 161 |
+
"""Descida multiplicativa (EG) de λ com hipergradiente EXATO + âncora.
|
| 162 |
+
|
| 163 |
+
Atualização: λ ← clip( λ·exp(−η·g), λmin, λmax ),
|
| 164 |
+
g = L_diff + 2ρ(λ−λ₀) (Teo 29.2-i — EXATO, L afim+quadrática)
|
| 165 |
+
|
| 166 |
+
Teo 29.2-ii (regret do EG, intervalo clipado): para L convexa com
|
| 167 |
+
|∂L/∂λ| ≤ G e λ ∈ [λmin,λmax], o regret cumulativo obedece
|
| 168 |
+
R_T ≤ η·G²·T/2 + ln(λmax/λmin)/η ≤ G·√(2·T·ln(λmax/λmin))
|
| 169 |
+
com η* = √(2·ln(λmax/λmin)/(G²T) — perda média ≤ ótimo + O(1/√T).
|
| 170 |
+
Teo 29.2-iii: com ρ>0, λ* = clip(λ₀ − L_diff/(2ρ)) é o ÚNICO
|
| 171 |
+
minimizador (L''=2ρ>0) — o controlador tem ÓTIMO INTERIOR provado
|
| 172 |
+
e o EG converge para a sua vizinhança O(η·G).
|
| 173 |
+
"""
|
| 174 |
+
|
| 175 |
+
def __init__(self, valor_inicial: float, eta: float = 0.05,
|
| 176 |
+
rho_ancora: float = 1.0, lambda0: float | None = None,
|
| 177 |
+
limites: tuple[float, float] = (1e-4, 1.0)):
|
| 178 |
+
self.valor = float(valor_inicial)
|
| 179 |
+
self.eta = float(eta)
|
| 180 |
+
self.rho = float(rho_ancora)
|
| 181 |
+
self.lambda0 = float(lambda0) if lambda0 is not None else self.valor
|
| 182 |
+
self.limites = (float(limites[0]), float(limites[1]))
|
| 183 |
+
self.historico: list[float] = [self.valor]
|
| 184 |
+
|
| 185 |
+
def passo_analitico(self, l_diff: float) -> float:
|
| 186 |
+
"""Passo FECHADO (âncora ρ>0): vai direto ao λ* clipado.
|
| 187 |
+
λ* = λ₀ − L_diff/(2ρ) — minimizador exato de L(λ) (Teo 29.2-iii).
|
| 188 |
+
Custo O(1), sem taxa de aprendizado — preferível quando a âncora
|
| 189 |
+
está ativa e L_diff é estável na janela."""
|
| 190 |
+
if self.rho <= 0:
|
| 191 |
+
return self.passo_eg(l_diff)
|
| 192 |
+
alvo = self.lambda0 - float(l_diff) / (2.0 * self.rho)
|
| 193 |
+
self.valor = max(self.limites[0], min(self.limites[1], alvo))
|
| 194 |
+
self.historico.append(self.valor)
|
| 195 |
+
return self.valor
|
| 196 |
+
|
| 197 |
+
def passo_eg(self, grad_lambda: float) -> float:
|
| 198 |
+
"""Passo EG multiplicativo (Teo 29.2-ii) — usado com ρ=0 ou como
|
| 199 |
+
suavização. grad_lambda = ∂L/∂λ (exato pela forma fechada)."""
|
| 200 |
+
self.valor *= math.exp(-self.eta * float(grad_lambda))
|
| 201 |
+
self.valor = max(self.limites[0], min(self.limites[1], self.valor))
|
| 202 |
+
self.historico.append(self.valor)
|
| 203 |
+
return self.valor
|
| 204 |
+
|
| 205 |
+
# compatibilidade com o rascunho (assinatura antiga `step`)
|
| 206 |
+
def step(self, grad_lambda: float) -> float:
|
| 207 |
+
return self.passo_eg(grad_lambda)
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def treinar_difusao(
|
| 211 |
+
modelo: DifusaoDDPM,
|
| 212 |
+
data: torch.Tensor,
|
| 213 |
+
passos: int = 2000,
|
| 214 |
+
lr: float = 1e-3,
|
| 215 |
+
device: str = "cpu",
|
| 216 |
+
ema: float = 0.0, # D2: >0 ativa EMA (default off = rascunho)
|
| 217 |
+
lambda_auto: AutoLambdaDiff | None = None, # D1: λ vivo opt-in
|
| 218 |
+
a_cada: int = 50,
|
| 219 |
+
) -> list[float]:
|
| 220 |
+
"""Loop de treino real com gradiente + autoajuste de λ vivo (D1).
|
| 221 |
+
|
| 222 |
+
λ_diff entra na perda via loss_ponderada; a cada `a_cada` passos o
|
| 223 |
+
controlador recebe o hipergradiente EXATO (Teo 29.2-i)."""
|
| 224 |
+
modelo.to(device).train()
|
| 225 |
+
opt = torch.optim.AdamW(modelo.net.parameters(), lr=lr)
|
| 226 |
+
historico: list[float] = []
|
| 227 |
+
for i in range(passos):
|
| 228 |
+
idx = torch.randint(0, data.shape[0], (64,), device=device)
|
| 229 |
+
x0 = data[idx].to(device)
|
| 230 |
+
if lambda_auto is not None:
|
| 231 |
+
l_total, tele = modelo.loss_ponderada(x0)
|
| 232 |
+
modelo.lambda_diff = torch.tensor(tele["lambda_diff"])
|
| 233 |
+
if (i + 1) % a_cada == 0:
|
| 234 |
+
lambda_auto.passo_analitico(tele["perda_difusao"])
|
| 235 |
+
else:
|
| 236 |
+
l_total = modelo.loss(x0)
|
| 237 |
+
opt.zero_grad(set_to_none=True)
|
| 238 |
+
l_total.backward()
|
| 239 |
+
opt.step()
|
| 240 |
+
if ema > 0:
|
| 241 |
+
modelo.ema_atualizar(ema)
|
| 242 |
+
historico.append(float(l_total.detach()))
|
| 243 |
+
return historico
|
src/khtst/aprimoramento/jepa.py
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""JEPA — v17 refatorada (doc 29 §7). Quatro correções sobre o rascunho:
|
| 3 |
+
|
| 4 |
+
D10 (CONDICIONAL MORTO): `z_t_p = self._project(z_t) if self.cfg.use_sg
|
| 5 |
+
else self._project(z_t)` — os DOIS ramos eram idênticos. Removido;
|
| 6 |
+
o stop-gradient é aplicado UMA vez, explicitamente.
|
| 7 |
+
|
| 8 |
+
D11 (VARIÂNCIA AGRUPADA — anti-colapso fraco): o rascunho calculava
|
| 9 |
+
`z.var(dim=(-2,-1))` — variância POOLADA sobre (T,D) e depois
|
| 10 |
+
média no lote. O hinge de VICReg é POR DIMENSÃO. Teo 29.10 (Jensen):
|
| 11 |
+
E_dims[relu(γ − σ_j)] ≥ relu(γ − E_dims[σ_j])
|
| 12 |
+
— o hinge POR DIMENSÃO é SEMPRE ≥ o poolado, com desigualdade
|
| 13 |
+
ESTRITA quando as dimensões têm desvios heterogêneos. Contraexemplo
|
| 14 |
+
concreto: dims com σ = (2, 0) — a variância poolada é grande, o
|
| 15 |
+
hinge poolado vale 0 e a dimensão B colapsada fica INVISÍVEL; o
|
| 16 |
+
per-dimensão cobra relu(1−0) = 1 dela. O colapso parcial (pior
|
| 17 |
+
caso prático — dims mortas que carregam informação perdida) só é
|
| 18 |
+
visto pelo per-dimensão.
|
| 19 |
+
|
| 20 |
+
D12 (TRUNCAMENTO DE COMPRIMENTO): o rascunho truncava para
|
| 21 |
+
L = min(Tc, Tt) — descartava a energia das posições além de L.
|
| 22 |
+
Correção (Teo 29.11): pooling adaptativo por média para o
|
| 23 |
+
comprimento comum — projeção L2 sobre o espaço mais grosso
|
| 24 |
+
(P² = P, P = Pᵀ ⟹ não-expansiva: ‖Pz‖ ≤ ‖z‖). O truncamento tem
|
| 25 |
+
erro de descarte E_trunc = Σ_{t>L}‖z_t‖²/E‖z‖² ≥ 0 enquanto o
|
| 26 |
+
pooling tem erro de resolução — dominado pelo de descarte quando
|
| 27 |
+
a energia é espalhada (caso típico de representações treinadas).
|
| 28 |
+
|
| 29 |
+
D13 (PESOS MORTOS): `cfg.lambda_jepa` (0.5) existia no config e NUNCA
|
| 30 |
+
era usado; o peso da variância era 0.01 hard-coded. Agora:
|
| 31 |
+
L_total = λ_jepa·L_alinhamento + peso_var·L_variância
|
| 32 |
+
com os dois pesos lidos do config (nascimento neutro: os defaults
|
| 33 |
+
λ=0.5, peso_var=0.01 reproduzem o rascunho quando λ_jepa=1 ... e o
|
| 34 |
+
caso λ=0.5 é o novo default DOCUMENTADO — o comportamento do
|
| 35 |
+
rascunho corresponde a λ_jepa=1.0, que o teste de regressão fixa).
|
| 36 |
+
|
| 37 |
+
Teo 29.12 (EMA cosseno — opt-in): m_t = 1 − (1−m₀)·(cos(πt/T)+1)/2
|
| 38 |
+
nasce em m₀ (alvo segue o encoder no arranque) e cresce
|
| 39 |
+
monotonamente até 1 (alvo congela quando a representação já
|
| 40 |
+
convergiu). Variância do ruído do alvo por passo: σ²_eff =
|
| 41 |
+
((1−m)/(1+m))·σ² — DECREASE com m (alvo mais silencioso no fim).
|
| 42 |
+
|
| 43 |
+
Teo 29.13 (COLAPSO NÃO É MÍNIMO LOCAL): no ponto colapsado (z constante),
|
| 44 |
+
o MSE é plano a 1ª ordem mas o hinge de variância está no MÁXIMO
|
| 45 |
+
(σ_j=0 ⟹ relu(γ−0)=γ) e qualquer perturbação o diminui ⟹ o colapso
|
| 46 |
+
não é mínimo local de L_total e a descida escapa. HONESTIDADE: em
|
| 47 |
+
σ=0 exato há kink (subdiferencial) — o autograd pode dar 0 no ponto
|
| 48 |
+
exato; a fuga é geométrica e a produção empurra a direção
|
| 49 |
+
explicitamente (yc/σ² do FunilLatente). peso_var > 0 é NECESSÁRIO.
|
| 50 |
+
|
| 51 |
+
Cython prioritário (requisito do projeto): quando `cfg.vicreg_lambda>0`
|
| 52 |
+
e o kernel compilado `khtst.treino.jepa_cython.vicreg_cython`
|
| 53 |
+
estiver disponível, o termo VICReg completo (invariância + variância
|
| 54 |
+
+ covariância) é delegado a ele; fallback PyTorch honesto.
|
| 55 |
+
"""
|
| 56 |
+
from __future__ import annotations
|
| 57 |
+
|
| 58 |
+
import copy
|
| 59 |
+
import math
|
| 60 |
+
from typing import Optional
|
| 61 |
+
|
| 62 |
+
import torch
|
| 63 |
+
import torch.nn as nn
|
| 64 |
+
import torch.nn.functional as F
|
| 65 |
+
|
| 66 |
+
from .config import JEPAConfig
|
| 67 |
+
|
| 68 |
+
try: # Cython prioritário — a ponte tem fallback PyTorch com as MESMAS
|
| 69 |
+
# convenções (import da ponte, não do kernel cru: degradação honesta)
|
| 70 |
+
from khtst.treino.jepa_cython import vicreg_cython as _vicreg_kernel
|
| 71 |
+
_TEM_VICREG = True
|
| 72 |
+
except Exception: # pragma: no cover
|
| 73 |
+
_vicreg_kernel = None
|
| 74 |
+
_TEM_VICREG = False
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
class MLP(nn.Module):
|
| 78 |
+
def __init__(self, dim_in: int, dim_hidden: int, dim_out: int):
|
| 79 |
+
super().__init__()
|
| 80 |
+
self.net = nn.Sequential(
|
| 81 |
+
nn.Linear(dim_in, dim_hidden),
|
| 82 |
+
nn.GELU(),
|
| 83 |
+
nn.LayerNorm(dim_hidden),
|
| 84 |
+
nn.Linear(dim_hidden, dim_hidden),
|
| 85 |
+
nn.GELU(),
|
| 86 |
+
nn.Linear(dim_hidden, dim_out),
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
def forward(self, x):
|
| 90 |
+
return self.net(x)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
class Encoder(nn.Module):
|
| 94 |
+
"""Encoder genérico — substitua por Mamba-3 + atenção em produção."""
|
| 95 |
+
|
| 96 |
+
def __init__(self, vocab: int, dim: int, n_layers: int = 4):
|
| 97 |
+
super().__init__()
|
| 98 |
+
self.emb = nn.Embedding(vocab, dim)
|
| 99 |
+
self.layers = nn.ModuleList([
|
| 100 |
+
nn.TransformerEncoderLayer(
|
| 101 |
+
d_model=dim, nhead=4, dim_feedforward=dim * 4,
|
| 102 |
+
batch_first=True, activation="gelu",
|
| 103 |
+
) for _ in range(n_layers)
|
| 104 |
+
])
|
| 105 |
+
self.norm = nn.LayerNorm(dim)
|
| 106 |
+
|
| 107 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 108 |
+
h = self.emb(x)
|
| 109 |
+
for layer in self.layers:
|
| 110 |
+
h = layer(h)
|
| 111 |
+
return self.norm(h)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
# ------------------------------ termo de variância --------------------------
|
| 115 |
+
|
| 116 |
+
def hinge_variancia_por_dim(z: torch.Tensor, gamma: float = 1.0) -> torch.Tensor:
|
| 117 |
+
"""Teo 29.10 — hinge de variância POR DIMENSÃO (anti-colapso forte).
|
| 118 |
+
|
| 119 |
+
z: (B, T, D) — achata para (B·T, D) e calcula σ_j por dimensão j
|
| 120 |
+
sobre o lote-tempo (populacional, correção=0 — mesma convenção
|
| 121 |
+
anti-NaN da v15.1: lote 1 não divide por zero)."""
|
| 122 |
+
flat = z.reshape(-1, z.shape[-1])
|
| 123 |
+
std = flat.std(dim=0, correction=0) + 1e-4
|
| 124 |
+
return F.relu(gamma - std).mean()
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
# ---------------------------------- JEPA ------------------------------------
|
| 128 |
+
|
| 129 |
+
class JEPA(nn.Module):
|
| 130 |
+
"""Joint Embedding Predictive Architecture (v17)."""
|
| 131 |
+
|
| 132 |
+
def __init__(self, encoder: nn.Module, cfg: JEPAConfig):
|
| 133 |
+
super().__init__()
|
| 134 |
+
self.cfg = cfg
|
| 135 |
+
self.online = encoder
|
| 136 |
+
self.target = copy.deepcopy(encoder)
|
| 137 |
+
for p in self.target.parameters():
|
| 138 |
+
p.requires_grad_(False)
|
| 139 |
+
self.predictor = MLP(cfg.dim, cfg.pred_hidden, cfg.dim)
|
| 140 |
+
self.pos_proj = nn.Linear(cfg.dim, cfg.dim)
|
| 141 |
+
self._t_ema = 0
|
| 142 |
+
|
| 143 |
+
@torch.no_grad()
|
| 144 |
+
def update_target(self):
|
| 145 |
+
m = self.momentum_efetivo()
|
| 146 |
+
for po, pt in zip(self.online.parameters(), self.target.parameters()):
|
| 147 |
+
pt.mul_(m).add_(po.detach(), alpha=1.0 - m)
|
| 148 |
+
for bo, bt in zip(self.online.buffers(), self.target.buffers()):
|
| 149 |
+
bt.copy_(bo)
|
| 150 |
+
|
| 151 |
+
def momentum_efetivo(self) -> float:
|
| 152 |
+
"""Teo 29.12 — agenda cosseno BYOL (opt-in) ou momentum fixo."""
|
| 153 |
+
m0 = self.cfg.ema_momentum
|
| 154 |
+
if not self.cfg.ema_cosseno:
|
| 155 |
+
return m0
|
| 156 |
+
# horizonte default: 100k passos (doc 29 §7.5); monótona m₀→1
|
| 157 |
+
T_h = 100_000
|
| 158 |
+
return 1.0 - (1.0 - m0) * (math.cos(math.pi * min(1.0, self._t_ema / T_h)) + 1.0) / 2.0
|
| 159 |
+
|
| 160 |
+
def _project(self, z: torch.Tensor) -> torch.Tensor:
|
| 161 |
+
return F.normalize(z, dim=-1) if self.cfg.normalize else z
|
| 162 |
+
|
| 163 |
+
@staticmethod
|
| 164 |
+
def _alinhar_comprimento(z_hat: torch.Tensor,
|
| 165 |
+
z_t: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
|
| 166 |
+
"""Teo 29.11 — pooling adaptativo (substitui o truncamento D12)."""
|
| 167 |
+
if z_hat.shape[1] == z_t.shape[1]:
|
| 168 |
+
return z_hat, z_t
|
| 169 |
+
L = min(z_hat.shape[1], z_t.shape[1])
|
| 170 |
+
# (B, T, D) → (B, D, T) → avg_pool1d → (B, D, L) → (B, L, D)
|
| 171 |
+
def pool(z):
|
| 172 |
+
return F.adaptive_avg_pool1d(z.transpose(1, 2), L).transpose(1, 2)
|
| 173 |
+
return pool(z_hat), pool(z_t)
|
| 174 |
+
|
| 175 |
+
def forward(
|
| 176 |
+
self,
|
| 177 |
+
ctx: torch.Tensor,
|
| 178 |
+
tgt: torch.Tensor,
|
| 179 |
+
pos_emb: Optional[torch.Tensor] = None,
|
| 180 |
+
) -> dict:
|
| 181 |
+
cfg = self.cfg
|
| 182 |
+
z_c = self.online(ctx) # (B, Tc, D)
|
| 183 |
+
# D10 corrigido: stop-gradient explícito e ÚNICO (o rascunho tinha
|
| 184 |
+
# um condicional com os dois ramos idênticos)
|
| 185 |
+
with torch.no_grad():
|
| 186 |
+
z_t = self.target(tgt) # (B, Tt, D)
|
| 187 |
+
z_t_p = self._project(z_t)
|
| 188 |
+
|
| 189 |
+
if pos_emb is None:
|
| 190 |
+
pos_emb = torch.zeros_like(z_c)
|
| 191 |
+
else:
|
| 192 |
+
pos_emb = self.pos_proj(pos_emb)
|
| 193 |
+
|
| 194 |
+
z_hat = self.predictor(z_c + pos_emb) # (B, Tc, D)
|
| 195 |
+
z_hat_p = self._project(z_hat)
|
| 196 |
+
|
| 197 |
+
# D12 corrigido: pooling adaptativo em vez de truncamento
|
| 198 |
+
z_hat_p, z_t_p = self._alinhar_comprimento(z_hat_p, z_t_p)
|
| 199 |
+
|
| 200 |
+
# D13 corrigido: pesos do CONFIG (λ_jepa era campo morto; 0.01
|
| 201 |
+
# era constante solta — agora peso_var do config)
|
| 202 |
+
mse = F.mse_loss(z_hat_p, z_t_p)
|
| 203 |
+
var_hat = hinge_variancia_por_dim(z_hat_p, 1.0)
|
| 204 |
+
var_tgt = hinge_variancia_por_dim(z_t_p, 1.0)
|
| 205 |
+
var_loss = var_hat + var_tgt
|
| 206 |
+
|
| 207 |
+
total = cfg.lambda_jepa * mse + cfg.peso_var * var_loss
|
| 208 |
+
|
| 209 |
+
# Cython prioritário: VICReg completo (invariância+var+cov) opt-in
|
| 210 |
+
vic_tele: dict = {}
|
| 211 |
+
if cfg.vicreg_lambda > 0.0 and _TEM_VICREG:
|
| 212 |
+
B, T, D = z_hat_p.shape
|
| 213 |
+
P = z_hat_p.reshape(-1, D)
|
| 214 |
+
Z = z_t_p.reshape(-1, D)
|
| 215 |
+
try:
|
| 216 |
+
L_v, partes = _vicreg_kernel(P, Z, 1.0, cfg.vicreg_mu,
|
| 217 |
+
cfg.vicreg_gamma)
|
| 218 |
+
total = total + cfg.vicreg_lambda * L_v
|
| 219 |
+
vic_tele = dict(partes)
|
| 220 |
+
except Exception as e: # pragma: no cover
|
| 221 |
+
vic_tele = {"motor": "fallback", "erro": str(e)}
|
| 222 |
+
|
| 223 |
+
# Teo 29.13 — telemetria do colapso: variância média por dimensão
|
| 224 |
+
with torch.no_grad():
|
| 225 |
+
std_por_dim = z_hat_p.reshape(-1, z_hat_p.shape[-1]).std(0, correction=0)
|
| 226 |
+
frac_colapsada = float((std_por_dim < 1e-2).float().mean())
|
| 227 |
+
|
| 228 |
+
self._t_ema += 1
|
| 229 |
+
return {"loss": total, "mse": mse.detach(), "var": var_loss.detach(),
|
| 230 |
+
"mu_ema": self.momentum_efetivo(),
|
| 231 |
+
"frac_colapsada": frac_colapsada,
|
| 232 |
+
"cython": _TEM_VICREG, **vic_tele}
|
| 233 |
+
|
| 234 |
+
def training_step(self, ctx, tgt, pos_emb=None) -> dict:
|
| 235 |
+
out = self.forward(ctx, tgt, pos_emb)
|
| 236 |
+
self.update_target()
|
| 237 |
+
return out
|
src/khtst/aprimoramento/lambda_c_unificado.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Autoajuste unificado de λ_c — v17 refatorada (doc 29 §5).
|
| 3 |
+
|
| 4 |
+
Elimina divergência entre caminho Cython (rápido) e Python (referência).
|
| 5 |
+
Fonte única: este módulo. `patches/correcoes.py` mantém a EQUAÇÃO
|
| 6 |
+
ESPECTRAL (intervalo do joelho — v15.1); ESTE módulo é o CONTROLADOR
|
| 7 |
+
TEMPORAL que rastreia o alvo ao longo do treino — as duas camadas são
|
| 8 |
+
complementares e a suíte v17 testa as duas.
|
| 9 |
+
|
| 10 |
+
Regra (v17, com os DOIS defeitos do rascunho corrigidos):
|
| 11 |
+
|
| 12 |
+
λ_c(t+1) = clip( λ_c(t) · exp( −η_t · Δ(t) ), λ_min, λ_max )
|
| 13 |
+
|
| 14 |
+
D6 (SINAL MORTO — defeito real): o rascunho computava a média móvel
|
| 15 |
+
`media` da janela e NUNCA a usava — o delta era o ε² INSTANTÂNEO,
|
| 16 |
+
com toda a variância amostral do passo. Correção (Teo 29.7-i):
|
| 17 |
+
modo="alvo": Δ(t) = ε̄²(t) − ε²_alvo
|
| 18 |
+
modo="reversao": Δ(t) = ε̄²(t) − média_janela(ε²)
|
| 19 |
+
com ε̄²(t) = média móvel da janela `janela`. REDUÇÃO DE VARIÂNCIA
|
| 20 |
+
provada: para amostras i.i.d. com variância σ², Var(média de W) =
|
| 21 |
+
σ²/W (Teo 29.7-i) — o sinal do controlador fica W vezes mais
|
| 22 |
+
quieto sem viés (média não-enviesada); Chebyshev:
|
| 23 |
+
P(|ε̄²−μ|>t) ≤ σ²/(W·t²).
|
| 24 |
+
|
| 25 |
+
D7 (PASSO CONSTANTE): η fixo só garante convergência a uma
|
| 26 |
+
VIZINHANÇA O(η) do ponto fixo. Correção (Teo 29.7-ii): modo
|
| 27 |
+
`eta_agendado=True` usa η_t = η₀/(1+t/τ) — satisfaz Ση_t = ∞ e
|
| 28 |
+
Ση_t² < ∞ ⟹ convergência q.c. (Robbins–Monro; Teo 28.5 reutilizado
|
| 29 |
+
— o campo de deriva b(u) = −η₀·Δ(ε̄²(u)) é Lipschitz no compacto
|
| 30 |
+
[λmin,λmax] e o ruído tem segundo momento finito).
|
| 31 |
+
|
| 32 |
+
Caminhos `fast_path_step`/`ref_path_step`: ref DELEGA a fast —
|
| 33 |
+
identidade bit-a-bit POR CONSTRUÇÃO, verificada numericamente a cada
|
| 34 |
+
suíte (n passos, max_diff == 0.0). A verificação SHA-256 das fontes é
|
| 35 |
+
mantida como auditoria (avisa divergência de arquivos, não é teste
|
| 36 |
+
matemático).
|
| 37 |
+
"""
|
| 38 |
+
from __future__ import annotations
|
| 39 |
+
|
| 40 |
+
from collections import deque
|
| 41 |
+
from dataclasses import dataclass, field
|
| 42 |
+
from typing import Deque
|
| 43 |
+
|
| 44 |
+
import numpy as np
|
| 45 |
+
|
| 46 |
+
from .config import LambdaCConfig
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
@dataclass
|
| 50 |
+
class EstadoLambdaC:
|
| 51 |
+
valor: float = 0.5
|
| 52 |
+
historico: Deque[float] = field(default_factory=lambda: deque(maxlen=1000))
|
| 53 |
+
eps_medio: Deque[float] = field(default_factory=lambda: deque(maxlen=100))
|
| 54 |
+
passo: int = 0
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
class AutoAjusteLambdaC:
|
| 58 |
+
"""Controlador temporal de λ_c com sinal suavizado VIVO (D6 corrigido)."""
|
| 59 |
+
|
| 60 |
+
def __init__(self, cfg: LambdaCConfig, eps_target: float = 1e-3):
|
| 61 |
+
self.cfg = cfg
|
| 62 |
+
self.eps_target = eps_target
|
| 63 |
+
self.estado = EstadoLambdaC(valor=0.5)
|
| 64 |
+
|
| 65 |
+
def step(self, eps2: float) -> float:
|
| 66 |
+
"""Um passo com o sinal da média da janela (Teo 29.7-i).
|
| 67 |
+
|
| 68 |
+
Regressão do defeito: no rascunho, `media` era calculada e o
|
| 69 |
+
delta usava `eps2` cru — a suíte v17 prova que, com janela cuja
|
| 70 |
+
média difere do instante, ESTE controlador responde à média."""
|
| 71 |
+
cfg = self.cfg
|
| 72 |
+
self.estado.eps_medio.append(float(eps2))
|
| 73 |
+
if len(self.estado.eps_medio) >= cfg.janela:
|
| 74 |
+
media = float(np.mean(self.estado.eps_medio))
|
| 75 |
+
if cfg.modo == "reversao":
|
| 76 |
+
# reversão à média da janela: o INSTANTÂNEO acima da média
|
| 77 |
+
# da janela empurra λ para baixo (e vice-versa)
|
| 78 |
+
delta = float(eps2) - media
|
| 79 |
+
else:
|
| 80 |
+
# modo alvo: sinal SUAVIZADO (média da janela) vs alvo fixo
|
| 81 |
+
delta = media - self.eps_target
|
| 82 |
+
if cfg.eta_agendado:
|
| 83 |
+
self.estado.passo += 1
|
| 84 |
+
eta_t = cfg.eta / (1.0 + self.estado.passo / cfg.tau_eta)
|
| 85 |
+
else:
|
| 86 |
+
eta_t = cfg.eta
|
| 87 |
+
novo = self.estado.valor * float(np.exp(-eta_t * delta))
|
| 88 |
+
novo = float(np.clip(novo, cfg.lambda_c_min, cfg.lambda_c_max))
|
| 89 |
+
self.estado.valor = novo
|
| 90 |
+
self.estado.historico.append(self.estado.valor)
|
| 91 |
+
return self.estado.valor
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# ------------------------- caminhos rápidos (equivalência) -----------------
|
| 95 |
+
|
| 96 |
+
def fast_path_step(lambda_prev: float, eps2: float, eps_target: float,
|
| 97 |
+
eta: float, lo: float, hi: float) -> float:
|
| 98 |
+
"""Compilável com @cython.boundscheck(False). Aqui: numpy puro."""
|
| 99 |
+
delta = eps2 - eps_target
|
| 100 |
+
novo = lambda_prev * np.exp(-eta * delta)
|
| 101 |
+
if novo < lo:
|
| 102 |
+
novo = lo
|
| 103 |
+
if novo > hi:
|
| 104 |
+
novo = hi
|
| 105 |
+
return float(novo)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def ref_path_step(lambda_prev: float, eps2: float, eps_target: float,
|
| 109 |
+
eta: float, lo: float, hi: float) -> float:
|
| 110 |
+
"""Referência Python — bit-a-bit idêntico ao fast (delega)."""
|
| 111 |
+
return fast_path_step(lambda_prev, eps2, eps_target, eta, lo, hi)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
# ------------------------------- auditoria --------------------------------
|
| 115 |
+
|
| 116 |
+
def sha256(path: str) -> str:
|
| 117 |
+
import hashlib
|
| 118 |
+
import pathlib
|
| 119 |
+
return hashlib.sha256(pathlib.Path(path).read_bytes()).hexdigest()
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def verificar_equivalencia_fontes(caminho_patch: str, caminho_quanta: str,
|
| 123 |
+
caminho_jepa: str) -> dict:
|
| 124 |
+
"""Compara SHA-256 dos três arquivos (AUDITORIA de integridade —
|
| 125 |
+
avisa divergência; o teste matemático canônico é o numérico abaixo)."""
|
| 126 |
+
hashes = {
|
| 127 |
+
"patch": sha256(caminho_patch),
|
| 128 |
+
"quanta": sha256(caminho_quanta),
|
| 129 |
+
"jepa": sha256(caminho_jepa),
|
| 130 |
+
}
|
| 131 |
+
ok = len(set(hashes.values())) == 1
|
| 132 |
+
return {"ok": ok, **hashes}
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def equivalencia_numerica(n: int = 10_000, seed: int = 42) -> dict:
|
| 136 |
+
"""Roda n passos em ambos caminhos e compara bit-a-bit (Teo 29.7-iii:
|
| 137 |
+
a equivalência é POR CONSTRUÇÃO — ref delega a fast; o teste fixa a
|
| 138 |
+
propriedade contra regressões de refatoração)."""
|
| 139 |
+
rng = np.random.default_rng(seed)
|
| 140 |
+
lam_f, lam_r = 0.5, 0.5
|
| 141 |
+
max_diff = 0.0
|
| 142 |
+
for _ in range(n):
|
| 143 |
+
eps2 = float(rng.uniform(1e-5, 1e-2))
|
| 144 |
+
lam_f = fast_path_step(lam_f, eps2, 1e-3, 1e-3, 0.01, 0.99)
|
| 145 |
+
lam_r = ref_path_step(lam_r, eps2, 1e-3, 1e-3, 0.01, 0.99)
|
| 146 |
+
max_diff = max(max_diff, abs(lam_f - lam_r))
|
| 147 |
+
return {"passos": n, "max_diff": max_diff, "identico": max_diff == 0.0}
|
src/khtst/aprimoramento/metricas_qe_ct.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Métricas QE + CT — v17 refatorada (doc 29 §4).
|
| 3 |
+
|
| 4 |
+
Substitutos do Erro Topológico (TE) com TRÊS correções sobre o rascunho
|
| 5 |
+
(defeitos D3/D4/D5 do doc 29):
|
| 6 |
+
|
| 7 |
+
D3 (ESCALA DEPENDENTE DA DIMENSÃO): o CT do rascunho somava ‖Δz‖² sobre
|
| 8 |
+
TODOS os eixos (B·D), logo crescia linearmente com B e D — dois
|
| 9 |
+
experimentos com dimensões diferentes eram incomparáveis. Correção
|
| 10 |
+
(Teo 29.4): CT_norm = Σ_t w_t·‖z_t − z_{t−1}‖²/(B·D) — energia de
|
| 11 |
+
deriva POR COORDENADA, invariante a mudança de lote/dimensão.
|
| 12 |
+
Prova da invariância: com z' = reindexação de z em (T, B'·D'),
|
| 13 |
+
‖Δz'‖² = (B'D'/BD)·‖Δz‖² (partição das coordenadas) ⟹ o quociente
|
| 14 |
+
é idêntico — CT_norm não vê a fatoração do eixo de características.
|
| 15 |
+
|
| 16 |
+
D4 (CONJUNÇÃO SEM SIGNIFICÂNCIA): `ganho = (Δ_QE < −ε) and (Δ_CT < −ε)`
|
| 17 |
+
com ε fixo é um teste de hipótese implícito SEM nível controlado —
|
| 18 |
+
com N amostras ruidosas, a taxa de falso-positivo não é limitada.
|
| 19 |
+
Correção (Teo 29.5): declara ganho real só se o limite superior de
|
| 20 |
+
confiança 1−α_f da MÉDIA de cada delta for < 0:
|
| 21 |
+
Student-t (default): UCB(Δ̄) = Δ̄_N + t_{1−α_f,N−1}·s/√N
|
| 22 |
+
— válido assintoticamente pelo TCL, sem suposição de suporte;
|
| 23 |
+
Hoeffding (opcional, raio DECLARADO R no config):
|
| 24 |
+
UCB(Δ̄) = Δ̄_N + R·√(ln(1/α_f)/(2N)) — válido em amostra
|
| 25 |
+
finita SE R ≥ range verdadeiro (suposição explícita; usar o
|
| 26 |
+
range OBSERVADO NÃO é válido — subestima o suporte).
|
| 27 |
+
α_f = α/2 (União de Bonferroni): P(falso ganho) ≤ 2·α_f = α
|
| 28 |
+
(Teo 29.5-i). Complexidade de amostra (Teo 29.5-ii): para detectar
|
| 29 |
+
efeito t sob Hoeffding é preciso N ≥ R²·ln(1/α_f)/(2t²) — o `n_min`
|
| 30 |
+
do cfg implementa o piso mínimo declarado.
|
| 31 |
+
|
| 32 |
+
D5 (te_antigo O(N·G)): a distância de cada amostra a TODOS os centros
|
| 33 |
+
da grade era O(N·G). Correção: scipy.spatial.cKDTree — consulta
|
| 34 |
+
O(log G) por amostra, O(N·log G) total (Teo 29.6-i). Equivalência
|
| 35 |
+
de resultado: para centro mínimo ÚNICO, a consulta devolve o MESMO
|
| 36 |
+
índice do argmin (Teo 29.6-ii); empates têm medida zero sob grades
|
| 37 |
+
com perturbação contínua — e a versão KDTree documenta o tie-break.
|
| 38 |
+
"""
|
| 39 |
+
from __future__ import annotations
|
| 40 |
+
|
| 41 |
+
from dataclasses import dataclass
|
| 42 |
+
|
| 43 |
+
import numpy as np
|
| 44 |
+
|
| 45 |
+
from .config import QECTConfig
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
@dataclass
|
| 49 |
+
class ResultadoQECT:
|
| 50 |
+
qe: float
|
| 51 |
+
ct: float
|
| 52 |
+
ganho_real: bool
|
| 53 |
+
delta_qe: float
|
| 54 |
+
delta_ct: float
|
| 55 |
+
# v17 — telemetria do teste de significância (Teo 29.5)
|
| 56 |
+
ucb_qe: float = 0.0
|
| 57 |
+
ucb_ct: float = 0.0
|
| 58 |
+
significativo: bool = False
|
| 59 |
+
n_amostras: int = 0
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def erro_quantizacao(x: np.ndarray, x_hat: np.ndarray,
|
| 63 |
+
normalizar: bool = False) -> float:
|
| 64 |
+
"""QE = (1/N)·Σ‖x − x̂‖²; com normalizar=True: QE/mean‖x‖² (D14 vivo).
|
| 65 |
+
|
| 66 |
+
Teo 29.4-i (invariância de escala): QE(αx, αx̂) = α²·QE(x, x̂) — o
|
| 67 |
+
QE relativo QE/mean‖x‖² é INVARIANTE a reescala global dos dados,
|
| 68 |
+
permitindo comparar camadas/épocas com energias distintas."""
|
| 69 |
+
assert x.shape == x_hat.shape, f"shapes {x.shape} vs {x_hat.shape}"
|
| 70 |
+
qe = float(np.mean(np.sum((x - x_hat) ** 2, axis=-1)))
|
| 71 |
+
if normalizar:
|
| 72 |
+
escala = float(np.mean(np.sum(x ** 2, axis=-1))) + 1e-12
|
| 73 |
+
qe = qe / escala
|
| 74 |
+
return qe
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def consistencia_temporal(z: np.ndarray,
|
| 78 |
+
ocupacao: np.ndarray | None = None,
|
| 79 |
+
por_coordenada: bool = True) -> float:
|
| 80 |
+
"""CT — deriva temporal ponderada por ocupação dos clusters.
|
| 81 |
+
|
| 82 |
+
z: (T, B, D) — representações latentes ao longo do tempo.
|
| 83 |
+
ocupacao: (T,) — ocupação do cluster em cada passo (padrão: uniforme).
|
| 84 |
+
|
| 85 |
+
v17 (Teo 29.4): por_coordenada=True divide por (B·D) — energia de
|
| 86 |
+
deriva POR COORDENADA, comparável entre configurações (correção D3).
|
| 87 |
+
O default preserva o valor ABSOLUTO do rascunho (comparabilidade de
|
| 88 |
+
regressão); os testes de ganho (avaliar_ganho) usam o normalizado.
|
| 89 |
+
"""
|
| 90 |
+
T = z.shape[0]
|
| 91 |
+
if ocupacao is None:
|
| 92 |
+
ocupacao = np.ones(T, dtype=float)
|
| 93 |
+
w = ocupacao / (ocupacao.sum() + 1e-12)
|
| 94 |
+
drifts = np.sum((z[1:] - z[:-1]) ** 2, axis=(-1, -2)) # (T-1,)
|
| 95 |
+
ct = float(np.sum(w[1:] * drifts))
|
| 96 |
+
if por_coordenada:
|
| 97 |
+
# Teo 29.4-ii: média POR COORDENADA — os pesos w já normalizam o
|
| 98 |
+
# eixo temporal (Σw=1), resta dividir por B·D (NÃO por (T−1)·B·D)
|
| 99 |
+
ct = ct / max(z.shape[1] * z.shape[2], 1)
|
| 100 |
+
return ct
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def _ucb_media(deltas: np.ndarray, alpha_f: float,
|
| 104 |
+
raio_declarado: float | None = None) -> float:
|
| 105 |
+
"""UCB 1−α_f da média (Teo 29.5).
|
| 106 |
+
|
| 107 |
+
Default: Student-t — UCB = Δ̄ + t_{1−α_f,N−1}·s/√N (TCL; sem
|
| 108 |
+
suposição de suporte; honesto para N ≥ n_min). Se `raio_declarado`
|
| 109 |
+
for passado, usa Hoeffding finito: Δ̄ + R·√(ln(1/α_f)/(2N)) —
|
| 110 |
+
válido somente sob a suposição EXPLÍCITA R ≥ range verdadeiro
|
| 111 |
+
(o range observado NÃO serve: subestima o suporte e invalida a
|
| 112 |
+
cota — Teo 29.5-iii)."""
|
| 113 |
+
n = len(deltas)
|
| 114 |
+
if n == 0:
|
| 115 |
+
return float("inf")
|
| 116 |
+
media = float(np.mean(deltas))
|
| 117 |
+
if raio_declarado is not None and raio_declarado > 0:
|
| 118 |
+
t = float(raio_declarado) * np.sqrt(np.log(1.0 / max(alpha_f, 1e-12))
|
| 119 |
+
/ (2.0 * n))
|
| 120 |
+
return media + t
|
| 121 |
+
from scipy import stats
|
| 122 |
+
s = float(np.std(deltas, ddof=1)) if n >= 2 else 0.0
|
| 123 |
+
tcrit = float(stats.t.ppf(1.0 - alpha_f, df=n - 1)) if n >= 2 else 0.0
|
| 124 |
+
return media + tcrit * s / np.sqrt(n)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def avaliar_ganho(
|
| 128 |
+
x: np.ndarray, x_hat_antes: np.ndarray, x_hat_depois: np.ndarray,
|
| 129 |
+
z_antes: np.ndarray, z_depois: np.ndarray,
|
| 130 |
+
cfg: QECTConfig,
|
| 131 |
+
) -> ResultadoQECT:
|
| 132 |
+
"""Avalia se houve ganho real segundo QE + CT com NÍVEL α (Teo 29.5).
|
| 133 |
+
|
| 134 |
+
ganho_real ⟺ UCB_{1−α/2}(Δ_QE) < 0 E UCB_{1−α/2}(Δ_CT) < 0 E n ≥ n_min
|
| 135 |
+
(conjunção com erro de família ≤ α pela União de Bonferroni — cada
|
| 136 |
+
delta testa no nível α/2)."""
|
| 137 |
+
norm = bool(getattr(cfg, "normalizar", False))
|
| 138 |
+
qe_a = erro_quantizacao(x, x_hat_antes, normalizar=norm)
|
| 139 |
+
qe_d = erro_quantizacao(x, x_hat_depois, normalizar=norm)
|
| 140 |
+
ct_a = consistencia_temporal(z_antes)
|
| 141 |
+
ct_d = consistencia_temporal(z_depois)
|
| 142 |
+
|
| 143 |
+
d_qe = qe_d - qe_a
|
| 144 |
+
d_ct = ct_d - ct_a
|
| 145 |
+
|
| 146 |
+
# amostras por passo: QE sobre N pontos; CT sobre (T−1) transições —
|
| 147 |
+
# o teste usa o MENOR n (honesto: o elo fraco comanda o nível)
|
| 148 |
+
n_qe = x.shape[0]
|
| 149 |
+
n_ct = max(z_antes.shape[0] - 1, 1)
|
| 150 |
+
n = min(n_qe, n_ct)
|
| 151 |
+
|
| 152 |
+
alpha_f = float(getattr(cfg, "alpha", 0.05)) / 2.0
|
| 153 |
+
# reconstrói as séries de deltas por amostra p/ Hoeffding:
|
| 154 |
+
# QE: erro quadrático por ponto; CT: deriva por transição.
|
| 155 |
+
e_qe_a = np.sum((x - x_hat_antes) ** 2, axis=-1)
|
| 156 |
+
e_qe_d = np.sum((x - x_hat_depois) ** 2, axis=-1)
|
| 157 |
+
if norm:
|
| 158 |
+
e_qe_a = e_qe_a / (np.sum(x ** 2, axis=-1).mean() + 1e-12)
|
| 159 |
+
e_qe_d = e_qe_d / (np.sum(x ** 2, axis=-1).mean() + 1e-12)
|
| 160 |
+
deltas_qe = e_qe_d - e_qe_a
|
| 161 |
+
dr_a = np.sum((z_antes[1:] - z_antes[:-1]) ** 2, axis=(-1, -2))
|
| 162 |
+
dr_d = np.sum((z_depois[1:] - z_depois[:-1]) ** 2, axis=(-1, -2))
|
| 163 |
+
T = z_antes.shape[0]
|
| 164 |
+
w = np.ones(T) / T
|
| 165 |
+
deltas_ct = w[1:] * (dr_d - dr_a)
|
| 166 |
+
|
| 167 |
+
ucb_qe = _ucb_media(deltas_qe, alpha_f)
|
| 168 |
+
ucb_ct = _ucb_media(deltas_ct, alpha_f)
|
| 169 |
+
n_min = int(getattr(cfg, "n_min", 32))
|
| 170 |
+
significativo = (ucb_qe < 0.0) and (ucb_ct < 0.0) and (n >= n_min)
|
| 171 |
+
|
| 172 |
+
# compatibilidade: limiares fixos continuam como condição NECESSÁRIA
|
| 173 |
+
# (não suficiente) — mantém a semântica do rascunho nos casos claros
|
| 174 |
+
ganho = significativo and (d_qe < -cfg.eps_qe) and (d_ct < -cfg.eps_ct)
|
| 175 |
+
return ResultadoQECT(qe_d, ct_d, bool(ganho), d_qe, d_ct,
|
| 176 |
+
ucb_qe=ucb_qe, ucb_ct=ucb_ct,
|
| 177 |
+
significativo=bool(significativo), n_amostras=int(n))
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def te_antigo(x: np.ndarray, x_hat: np.ndarray, grid: np.ndarray) -> float:
|
| 181 |
+
"""TE legado — distância média ao centro de grade mais próximo.
|
| 182 |
+
|
| 183 |
+
v17 (Teo 29.6): consulta via cKDTree — O((G+N)·log G) em vez de
|
| 184 |
+
O(N·G). Para centro mínimo único, devolve o MESMO valor do argmin
|
| 185 |
+
exaustivo (verificado bit-a-bit na suíte v17); empates exatos têm
|
| 186 |
+
medida zero sob grades contínuas e o tie-break do KDTree é
|
| 187 |
+
documentado (menor índice não garantido — diferença só em empate)."""
|
| 188 |
+
from scipy.spatial import cKDTree
|
| 189 |
+
arvore = cKDTree(grid)
|
| 190 |
+
d, _ = arvore.query(x, k=1)
|
| 191 |
+
return float(np.mean(d))
|
src/khtst/aprimoramento/tradeoff_k.py
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""Trade-off de K — v17 refatorada (doc 29 §6).
|
| 3 |
+
|
| 4 |
+
Métodos: RD (J1), assintótico (J2) e grade (auditoria).
|
| 5 |
+
|
| 6 |
+
NOVOS TEOREMAS desta revisão (provas completas no doc 29):
|
| 7 |
+
|
| 8 |
+
Teo 29.9-i (UNIMODALIDADE — garante que minimize_scalar bounded acha o
|
| 9 |
+
mínimo GLOBAL). Com ε²(K) = C·K^{−2/d} (Zador) e
|
| 10 |
+
J1(K) = (1−λ)·C·K^{−2/d} + λ·(log₂K + K·d/n)/log₂d,
|
| 11 |
+
a derivada é
|
| 12 |
+
J1'(K) = −(1−λ)C·p·K^{−p−1} + λ·(K^{−1}/ln2 + d/n)/log₂d, p = 2/d.
|
| 13 |
+
Multiplicando por K^{p+1} > 0:
|
| 14 |
+
G(K) = −(1−λ)C·p + λ·(K^p/ln2 + K^{p+1}·d/n)/log₂d.
|
| 15 |
+
G é ESTRITAMENTE CRESCENTE em K (K^p e K^{p+1} o são, coeficientes
|
| 16 |
+
> 0) ⟹ G tem no máximo uma raiz ⟹ J1' muda de sinal no máximo uma
|
| 17 |
+
vez. Como J1'(K) → −∞ quando K→0⁺ (K^{−p−1} domina K^{−1} pois
|
| 18 |
+
p+1 > 1) e J1'(K) → λ·d/(n·log₂d) ≥ 0 quando K→∞, J1 decresce e
|
| 19 |
+
depois cresce — MÍNIMO GLOBAL ÚNICO. Nenhuma aproximação.
|
| 20 |
+
|
| 21 |
+
Teo 29.9-ii (FORMA FECHADA no regime n→∞): G(K)=0 dá
|
| 22 |
+
K* = [ (1−λ)·2·C·ln d / (λ·d) ]^{d/2}
|
| 23 |
+
(usando ln2·log₂d = ln d). Usada como INITIALIZATION/bracket do
|
| 24 |
+
minimizador numérico e como sanity check (o teste v17 compara a
|
| 25 |
+
forma fechada com a raiz numérica — coincidência a 1e-6 relativo).
|
| 26 |
+
|
| 27 |
+
Teo 29.9-iii (SENSIBILIDADE — honestidade): da forma fechada,
|
| 28 |
+
∂ln K*/∂ln C = d/2 — para d grande, K* é MUITO sensível a C. Por
|
| 29 |
+
isso Ĉ é estimado com SHRINKAGE ao prior: Ĉ = (n_C·Ĉ_ols + κ·C₀)/
|
| 30 |
+
(n_C + κ) — troca viés por variância com peso explícito (James–
|
| 31 |
+
Stein simplificado; o κ do config expõe o trade-off).
|
| 32 |
+
|
| 33 |
+
D8 (C=1 FIXO — defeito do rascunho): a constante de Zador depende da
|
| 34 |
+
DISTRIBUIÇÃO (segundo momento normalizado da célula de Voronoi —
|
| 35 |
+
nunca é 1 em dados reais). Correção (Teo 29.8): medir ε²(K) na
|
| 36 |
+
grade e ajustar OLS em log-log: ln ε² = ln C − (2/d)·ln K + r;
|
| 37 |
+
consistência por LLN (r média-zero i.i.d. ⟹ (Ĉ, p̂) → (C, 2/d));
|
| 38 |
+
a INCLINAÇÃO ESTIMADA p̂ serve de TESTE DO MODELO: |p̂ + 2/d| grande
|
| 39 |
+
⟹ o modelo de Zador não vale para esses dados ⟹ cai para a grade
|
| 40 |
+
(honestidade metodológica, registrada na telemetria).
|
| 41 |
+
|
| 42 |
+
D9 (λ_c ESTÁTICO): o rascunho lia λ do config e nunca o atualizava;
|
| 43 |
+
agora `resolver_K` aceita λ_c adaptativo (saída do
|
| 44 |
+
AutoAjusteLambdaC — integração λ_c ↔ K* pela mesma unidade de
|
| 45 |
+
trade-off distorção×custo).
|
| 46 |
+
"""
|
| 47 |
+
from __future__ import annotations
|
| 48 |
+
|
| 49 |
+
import math
|
| 50 |
+
from dataclasses import dataclass, field
|
| 51 |
+
from typing import Dict, Tuple
|
| 52 |
+
|
| 53 |
+
import numpy as np
|
| 54 |
+
from scipy.optimize import minimize_scalar
|
| 55 |
+
|
| 56 |
+
from .config import TradeoffKConfig
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# ------------------ modelo de erro de quantização (Zador) ------------------
|
| 60 |
+
|
| 61 |
+
def epsilon_sq(K, d: int, C: float = 1.0):
|
| 62 |
+
"""Erro de quantização empírico ~ C·K^{−2/d} (Zador, alta resolução).
|
| 63 |
+
|
| 64 |
+
Domínio: K ≥ 1 (o modelo não é definido abaixo do codebook unitário;
|
| 65 |
+
K<1 é clampeado — elimina NaN de potências fracionárias negativas)."""
|
| 66 |
+
K = np.asarray(K, dtype=float)
|
| 67 |
+
return C * np.maximum(K, 1.0) ** (-2.0 / d)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def estimar_C(K_medidos, e2_medidos, d: int, C_prior: float = 1.0,
|
| 71 |
+
kappa: int = 8) -> dict:
|
| 72 |
+
"""Teo 29.8 — Ĉ por OLS log-log + teste do modelo + shrinkage.
|
| 73 |
+
|
| 74 |
+
Regressão: y_i = ln e2_i, x_i = ln K_i ⟹ y = a − p·x com a = ln C.
|
| 75 |
+
Ĉ_ols = exp(â); p̂ é a inclinação — se o modelo vale, p̂ ≈ 2/d.
|
| 76 |
+
Shrinkage: Ĉ = (n_C·Ĉ_ols + κ·C₀)/(n_C + κ)."""
|
| 77 |
+
K = np.asarray(K_medidos, dtype=float)
|
| 78 |
+
e2 = np.asarray(e2_medidos, dtype=float)
|
| 79 |
+
ok = (K > 0) & (e2 > 0)
|
| 80 |
+
K, e2 = K[ok], e2[ok]
|
| 81 |
+
n_c = int(K.size)
|
| 82 |
+
if n_c < 2:
|
| 83 |
+
return {"C": float(C_prior), "incl": float("nan"),
|
| 84 |
+
"modelo_ok": False, "n": n_c}
|
| 85 |
+
x, y = np.log(K), np.log(e2)
|
| 86 |
+
# OLS fechado (1D): y = a + b·x com b = incl ⟹ a = ȳ − b·x̄
|
| 87 |
+
# (C = exp(a); inclinação b ≈ −2/d se o modelo de Zador vale)
|
| 88 |
+
xm, ym = x.mean(), y.mean()
|
| 89 |
+
denom = float(((x - xm) ** 2).sum()) + 1e-12
|
| 90 |
+
incl = float(((x - xm) * (y - ym)).sum() / denom)
|
| 91 |
+
a = float(ym - incl * xm) # intercepto correto (y = a + b·x)
|
| 92 |
+
c_ols = math.exp(a)
|
| 93 |
+
modelo_ok = abs(incl + 2.0 / d) <= max(0.35, 0.5 * (2.0 / d))
|
| 94 |
+
c_shrunk = (n_c * c_ols + kappa * float(C_prior)) / (n_c + kappa)
|
| 95 |
+
return {"C": float(c_shrunk), "C_ols": float(c_ols),
|
| 96 |
+
"incl": incl, "modelo_ok": bool(modelo_ok), "n": n_c}
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
# --------------------------------- métodos ---------------------------------
|
| 100 |
+
|
| 101 |
+
def J1(K: float, d: int, n: int, lam: float, C: float = 1.0,
|
| 102 |
+
bits_por_param: float = 16.0) -> float:
|
| 103 |
+
"""J1 = (1−λ)·ε²(K) + λ·(log₂K + K·d/n)/log₂d — com C estimado (D8)."""
|
| 104 |
+
eps = float(epsilon_sq(K, d, C))
|
| 105 |
+
bits = (np.log2(max(K, 2)) + K * d / n
|
| 106 |
+
* (bits_por_param / 16.0)) / np.log2(max(d, 2))
|
| 107 |
+
return (1 - lam) * eps + lam * bits
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def J2(K: float, d: int, lam: float, C: float = 1.0) -> float:
|
| 111 |
+
eps = float(epsilon_sq(K, d, C))
|
| 112 |
+
return eps + lam * K / np.sqrt(d)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def k_star_fechado(d: int, lam: float, C: float = 1.0) -> float:
|
| 116 |
+
"""Teo 29.9-ii — K* = [(1−λ)·2·C·ln d/(λ·d)]^{d/2} (regime n→∞)."""
|
| 117 |
+
if not (0.0 < lam < 1.0) or C <= 0 or d < 2:
|
| 118 |
+
return float("nan")
|
| 119 |
+
return ((1.0 - lam) * 2.0 * C * math.log(d) / (lam * d)) ** (d / 2.0)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def K_star_rd(cfg: TradeoffKConfig, C: float | None = None) -> float:
|
| 123 |
+
"""Mínimo GLOBAL de J1 por minimize_scalar bounded (Teo 29.9-i garante
|
| 124 |
+
que o mínimo local é o global). Bracket centrado na forma fechada
|
| 125 |
+
quando disponível (Teo 29.9-ii) — acelera e ancora a busca."""
|
| 126 |
+
C = C if C is not None else 1.0
|
| 127 |
+
k_hint = k_star_fechado(cfg.d, cfg.lambda_c, C)
|
| 128 |
+
lo, hi = 4.0, 4096.0
|
| 129 |
+
if math.isfinite(k_hint) and k_hint > 0:
|
| 130 |
+
lo = max(4.0, k_hint / 8.0)
|
| 131 |
+
hi = min(4096.0, max(k_hint * 8.0, 32.0))
|
| 132 |
+
if lo >= hi:
|
| 133 |
+
lo, hi = 4.0, 4096.0
|
| 134 |
+
res = minimize_scalar(
|
| 135 |
+
lambda k: J1(k, cfg.d, cfg.n, cfg.lambda_c, C, cfg.bits_por_param),
|
| 136 |
+
bounds=(lo, hi), method="bounded",
|
| 137 |
+
)
|
| 138 |
+
return float(res.x)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def K_star_asymp(cfg: TradeoffKConfig, C: float | None = None) -> float:
|
| 142 |
+
C = C if C is not None else 1.0
|
| 143 |
+
res = minimize_scalar(
|
| 144 |
+
lambda k: J2(k, cfg.d, cfg.lambda_c, C),
|
| 145 |
+
bounds=(4, 4096), method="bounded",
|
| 146 |
+
)
|
| 147 |
+
return float(res.x)
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
def K_star_grid(cfg: TradeoffKConfig, C: float | None = None) -> float:
|
| 151 |
+
vals = [(k, J1(k, cfg.d, cfg.n, cfg.lambda_c, C, cfg.bits_por_param))
|
| 152 |
+
for k in cfg.K_grid]
|
| 153 |
+
return float(min(vals, key=lambda t: t[1])[0])
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
# ----------------------------- orquestrador --------------------------------
|
| 157 |
+
|
| 158 |
+
@dataclass
|
| 159 |
+
class ResultadoK:
|
| 160 |
+
K_rd: float
|
| 161 |
+
K_asymp: float
|
| 162 |
+
K_grid: float
|
| 163 |
+
divergencia: float
|
| 164 |
+
metodo_escolhido: str
|
| 165 |
+
K_final: float
|
| 166 |
+
tabela: Dict[str, float]
|
| 167 |
+
# v17 — telemetria da estimação de C (D8) e do modelo de Zador
|
| 168 |
+
C_estimado: float = 1.0
|
| 169 |
+
C_ols: float = 1.0
|
| 170 |
+
inclinacao: float = float("nan")
|
| 171 |
+
modelo_ok: bool = False
|
| 172 |
+
K_fechado: float = float("nan")
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def medir_epsilon_sq(dados: np.ndarray, K_medidos, seed: int = 0) -> Tuple[np.ndarray, np.ndarray]:
|
| 176 |
+
"""Mede ε²(K) REAL por quantização por k-means leve (Teo 29.8).
|
| 177 |
+
|
| 178 |
+
Usado quando `estimar_C=True` e dados estão disponíveis; sem dados,
|
| 179 |
+
o chamador pode passar pares (K, ε²) medidos por outra via (ex.:
|
| 180 |
+
espectro PCA via Eckart–Young — patches/correcoes.py)."""
|
| 181 |
+
Ks = np.asarray(list(K_medidos), dtype=int)
|
| 182 |
+
e2 = []
|
| 183 |
+
rng = np.random.default_rng(seed)
|
| 184 |
+
amostra = dados[np.random.default_rng(seed).choice(
|
| 185 |
+
dados.shape[0], size=min(4096, dados.shape[0]), replace=False)]
|
| 186 |
+
for k in Ks:
|
| 187 |
+
# k-means 1 inicialização + 8 iterações de Lloyd (leve, auditável)
|
| 188 |
+
centros = amostra[rng.choice(amostra.shape[0], size=k, replace=False)]
|
| 189 |
+
for _ in range(8):
|
| 190 |
+
d2 = ((amostra[:, None, :] - centros[None, :, :]) ** 2).sum(-1)
|
| 191 |
+
lab = d2.argmin(1)
|
| 192 |
+
for j in range(k):
|
| 193 |
+
pts = amostra[lab == j]
|
| 194 |
+
if len(pts):
|
| 195 |
+
centros[j] = pts.mean(0)
|
| 196 |
+
d2 = ((amostra[:, None, :] - centros[None, :, :]) ** 2).sum(-1)
|
| 197 |
+
e2.append(float(d2.min(1).mean()))
|
| 198 |
+
return Ks.astype(float), np.asarray(e2)
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def resolver_K(cfg: TradeoffKConfig,
|
| 202 |
+
pares_medidos: Tuple[np.ndarray, np.ndarray] | None = None,
|
| 203 |
+
lambda_c_adaptativo: float | None = None) -> ResultadoK:
|
| 204 |
+
"""Resolve K* com Ĉ estimado (D8) e λ_c adaptativo (D9).
|
| 205 |
+
|
| 206 |
+
pares_medidos: (K, ε²) medidos — alimenta o OLS de Ĉ. Sem eles e com
|
| 207 |
+
estimar_C=True, usa o prior (honesto: registra modelo_ok=False)."""
|
| 208 |
+
lam = float(lambda_c_adaptativo) if lambda_c_adaptativo is not None \
|
| 209 |
+
else float(cfg.lambda_c)
|
| 210 |
+
C_hat, C_ols, incl, modelo_ok = 1.0, 1.0, float("nan"), False
|
| 211 |
+
if cfg.estimar_C and pares_medidos is not None:
|
| 212 |
+
est = estimar_C(pares_medidos[0], pares_medidos[1], cfg.d,
|
| 213 |
+
cfg.C_prior, cfg.kappa_prior)
|
| 214 |
+
C_hat, C_ols, incl = est["C"], est["C_ols"], est["incl"]
|
| 215 |
+
modelo_ok = est["modelo_ok"]
|
| 216 |
+
|
| 217 |
+
cfg_lam = TradeoffKConfig(
|
| 218 |
+
d=cfg.d, n=cfg.n, lambda_c=lam, K_grid=cfg.K_grid,
|
| 219 |
+
tol_rel=cfg.tol_rel, metodo=cfg.metodo,
|
| 220 |
+
estimar_C=cfg.estimar_C, C_prior=cfg.C_prior,
|
| 221 |
+
kappa_prior=cfg.kappa_prior, bits_por_param=cfg.bits_por_param)
|
| 222 |
+
|
| 223 |
+
k_rd = K_star_rd(cfg_lam, C_hat)
|
| 224 |
+
k_as = K_star_asymp(cfg_lam, C_hat)
|
| 225 |
+
k_gr = K_star_grid(cfg_lam, C_hat)
|
| 226 |
+
|
| 227 |
+
div = abs(k_rd - k_as) / max(k_rd, 1e-9)
|
| 228 |
+
|
| 229 |
+
if cfg.metodo == "auto":
|
| 230 |
+
# Teo 29.8 (honestidade): modelo de Zador ruim ⟹ confia na grade
|
| 231 |
+
if (not modelo_ok) and pares_medidos is not None:
|
| 232 |
+
escolhido, k_final = "grid", k_gr
|
| 233 |
+
elif div < cfg.tol_rel:
|
| 234 |
+
escolhido, k_final = "rd", k_rd
|
| 235 |
+
else:
|
| 236 |
+
escolhido, k_final = "grid", k_gr
|
| 237 |
+
else:
|
| 238 |
+
escolhido = cfg.metodo
|
| 239 |
+
k_final = {"rd": k_rd, "asymp": k_as, "grid": k_gr}[cfg.metodo]
|
| 240 |
+
|
| 241 |
+
return ResultadoK(
|
| 242 |
+
K_rd=k_rd, K_asymp=k_as, K_grid=k_gr,
|
| 243 |
+
divergencia=div, metodo_escolhido=escolhido,
|
| 244 |
+
K_final=k_final,
|
| 245 |
+
tabela={str(k): J1(k, cfg.d, cfg.n, lam, C_hat, cfg.bits_por_param)
|
| 246 |
+
for k in cfg.K_grid},
|
| 247 |
+
C_estimado=float(C_hat), C_ols=float(C_ols),
|
| 248 |
+
inclinacao=float(incl), modelo_ok=bool(modelo_ok),
|
| 249 |
+
K_fechado=float(k_star_fechado(cfg.d, lam, C_hat)))
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def validar_v15_1() -> Dict[int, Tuple[float, float]]:
|
| 253 |
+
"""Compara K* bugado (b(K)=log₂K/log₂d) com K* corrigido (rate-distortion)."""
|
| 254 |
+
out = {}
|
| 255 |
+
for d in (64, 512, 4096):
|
| 256 |
+
def J_bug(k, d=d):
|
| 257 |
+
return float(epsilon_sq(k, d)) + 0.5 * np.log2(max(k, 2)) / np.log2(d)
|
| 258 |
+
r_bug = minimize_scalar(J_bug, bounds=(4, 512), method="bounded")
|
| 259 |
+
cfg = TradeoffKConfig(d=d, n=100_000, lambda_c=0.5)
|
| 260 |
+
r_fix = K_star_rd(cfg)
|
| 261 |
+
out[d] = (float(r_bug.x), float(r_fix))
|
| 262 |
+
return out
|
src/khtst/mamba3/__pycache__/hybrid.cpython-312.pyc
DELETED
|
Binary file (19.8 kB)
|
|
|
src/khtst/mamba3/__pycache__/kernel.cpython-312.pyc
DELETED
|
Binary file (6.12 kB)
|
|
|
src/khtst/mamba3/__pycache__/replay.cpython-312.pyc
DELETED
|
Binary file (5 kB)
|
|
|
src/khtst/mamba3/hybrid.py
CHANGED
|
@@ -37,11 +37,11 @@ import torch.nn.functional as F
|
|
| 37 |
from torch.utils.checkpoint import checkpoint
|
| 38 |
|
| 39 |
from khtst.mamba3.kernel import varredura_trapezoidal
|
| 40 |
-
from khtst.mamba3.replay import varredura_replay
|
| 41 |
|
| 42 |
__all__ = ["NoPEAtencao", "Mamba3Camada", "HybridMamba3Modelo",
|
| 43 |
"eh_camada_atencao", "EstadoMamba3"]
|
| 44 |
|
|
|
|
| 45 |
class EstadoMamba3:
|
| 46 |
"""Estado recorrente de UMA Mamba3Camada para decode INCREMENTAL
|
| 47 |
(v12, Teorema 24.13 — equivalência exata com a varredura paralela):
|
|
@@ -141,15 +141,11 @@ class Mamba3Camada(nn.Module):
|
|
| 141 |
"""Camada MAMBA-3 com gate SiLU + pré-norm + residual (doc 22 §3)."""
|
| 142 |
|
| 143 |
def __init__(self, d_modelo: int, d_estado: int = 16, rank_mimo: int = 4,
|
| 144 |
-
kernel_conv: int = 4
|
| 145 |
super().__init__()
|
| 146 |
self.d = d_modelo
|
| 147 |
self.n = d_estado
|
| 148 |
self.r = rank_mimo
|
| 149 |
-
self.k_conv = kernel_conv
|
| 150 |
-
# v17 (doc 29, Teos 29.13–29.14) — ReplaySSM: nº de segmentos da
|
| 151 |
-
# varredura (0 = desligado ⟹ v12 exato, nascimento neutro)
|
| 152 |
-
self.replay_segmento = int(replay_segmento)
|
| 153 |
self.entrada_proj = nn.Linear(d_modelo, 2 * d_modelo, bias=False)
|
| 154 |
self.conv1d = nn.Conv1d(d_modelo, d_modelo, kernel_size=kernel_conv,
|
| 155 |
padding=0, groups=d_modelo) # causal manual
|
|
@@ -188,20 +184,7 @@ class Mamba3Camada(nn.Module):
|
|
| 188 |
uc = F.pad(u.transpose(1, 2), (self.k_conv - 1, 0))
|
| 189 |
uc = self.conv1d(uc).transpose(1, 2).contiguous() # (B,L,D)
|
| 190 |
delta, B_m, C_m = self._projetos(uc)
|
| 191 |
-
|
| 192 |
-
# com replay de estados fronteira (gradiente e saída EXATOS;
|
| 193 |
-
# ativação O(S·BDN + L_s·BDN)). Só em treino com gradiente e
|
| 194 |
-
# L > 1 — decode incremental (T=1) nunca segmenta.
|
| 195 |
-
seg = int(getattr(self, "replay_segmento", 0) or 0)
|
| 196 |
-
if seg > 1 and self.training and torch.is_grad_enabled() and L > seg:
|
| 197 |
-
if devolve_estado:
|
| 198 |
-
y, h_final = varredura_replay(uc, delta, self.A, B_m, C_m,
|
| 199 |
-
n_segmentos=seg,
|
| 200 |
-
devolve_estado=True)
|
| 201 |
-
else:
|
| 202 |
-
y = varredura_replay(uc, delta, self.A, B_m, C_m,
|
| 203 |
-
n_segmentos=seg)
|
| 204 |
-
elif devolve_estado:
|
| 205 |
y, h_final = varredura_trapezoidal(uc, delta, self.A, B_m,
|
| 206 |
C_m, devolve_estado=True)
|
| 207 |
else:
|
|
@@ -254,7 +237,7 @@ class HybridMamba3Modelo(nn.Module):
|
|
| 254 |
|
| 255 |
def __init__(self, d_modelo: int, n_camadas: int = 6, n_cabecas: int = 4,
|
| 256 |
d_estado: int = 16, rank_mimo: int = 4,
|
| 257 |
-
grad_checkpointing: bool = True
|
| 258 |
super().__init__()
|
| 259 |
self.d = d_modelo
|
| 260 |
self.n_camadas = n_camadas
|
|
@@ -265,8 +248,7 @@ class HybridMamba3Modelo(nn.Module):
|
|
| 265 |
self.camadas.append(NoPEAtencao(d_modelo, n_cabecas))
|
| 266 |
else:
|
| 267 |
self.camadas.append(
|
| 268 |
-
Mamba3Camada(d_modelo, d_estado, rank_mimo
|
| 269 |
-
replay_segmento=replay_segmento))
|
| 270 |
self.norm_f = nn.RMSNorm(d_modelo)
|
| 271 |
|
| 272 |
def _corre(self, x: torch.Tensor, tarefa=None) -> torch.Tensor:
|
|
|
|
| 37 |
from torch.utils.checkpoint import checkpoint
|
| 38 |
|
| 39 |
from khtst.mamba3.kernel import varredura_trapezoidal
|
|
|
|
| 40 |
|
| 41 |
__all__ = ["NoPEAtencao", "Mamba3Camada", "HybridMamba3Modelo",
|
| 42 |
"eh_camada_atencao", "EstadoMamba3"]
|
| 43 |
|
| 44 |
+
|
| 45 |
class EstadoMamba3:
|
| 46 |
"""Estado recorrente de UMA Mamba3Camada para decode INCREMENTAL
|
| 47 |
(v12, Teorema 24.13 — equivalência exata com a varredura paralela):
|
|
|
|
| 141 |
"""Camada MAMBA-3 com gate SiLU + pré-norm + residual (doc 22 §3)."""
|
| 142 |
|
| 143 |
def __init__(self, d_modelo: int, d_estado: int = 16, rank_mimo: int = 4,
|
| 144 |
+
kernel_conv: int = 4):
|
| 145 |
super().__init__()
|
| 146 |
self.d = d_modelo
|
| 147 |
self.n = d_estado
|
| 148 |
self.r = rank_mimo
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
self.entrada_proj = nn.Linear(d_modelo, 2 * d_modelo, bias=False)
|
| 150 |
self.conv1d = nn.Conv1d(d_modelo, d_modelo, kernel_size=kernel_conv,
|
| 151 |
padding=0, groups=d_modelo) # causal manual
|
|
|
|
| 184 |
uc = F.pad(u.transpose(1, 2), (self.k_conv - 1, 0))
|
| 185 |
uc = self.conv1d(uc).transpose(1, 2).contiguous() # (B,L,D)
|
| 186 |
delta, B_m, C_m = self._projetos(uc)
|
| 187 |
+
if devolve_estado:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
y, h_final = varredura_trapezoidal(uc, delta, self.A, B_m,
|
| 189 |
C_m, devolve_estado=True)
|
| 190 |
else:
|
|
|
|
| 237 |
|
| 238 |
def __init__(self, d_modelo: int, n_camadas: int = 6, n_cabecas: int = 4,
|
| 239 |
d_estado: int = 16, rank_mimo: int = 4,
|
| 240 |
+
grad_checkpointing: bool = True):
|
| 241 |
super().__init__()
|
| 242 |
self.d = d_modelo
|
| 243 |
self.n_camadas = n_camadas
|
|
|
|
| 248 |
self.camadas.append(NoPEAtencao(d_modelo, n_cabecas))
|
| 249 |
else:
|
| 250 |
self.camadas.append(
|
| 251 |
+
Mamba3Camada(d_modelo, d_estado, rank_mimo))
|
|
|
|
| 252 |
self.norm_f = nn.RMSNorm(d_modelo)
|
| 253 |
|
| 254 |
def _corre(self, x: torch.Tensor, tarefa=None) -> torch.Tensor:
|