File size: 7,239 Bytes
00eab41 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | #!/usr/bin/env python3
"""
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 𧬠CROM-IA V2: Decoder Streaming DNA β Texto Humano β
β β
β Recebe tokens DNA do llama-cli via stdin (pipe) β
β Decodifica usando codebook semΓ’ntico (hashmap O(1)) β
β Emite texto humano em tempo real via stdout β
β Emite mΓ©tricas SRE no stderr ao final β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Uso:
llama-cli -m model.gguf -p "..." | python3 dna_decoder.py --codebook codebook_1x3_fixo.json
"""
import os
import sys
import json
import time
import argparse
def carregar_codebook(caminho):
"""Carrega codebook e prepara hashmap de lookup."""
with open(caminho, 'r', encoding='utf-8') as f:
codebook = json.load(f)
entries = codebook.get("entries", {})
escape = codebook.get("escape_prefix", "@@")
taxa = codebook.get("taxa_alvo", "?")
modo = codebook.get("modo", "?")
sys.stderr.write(f"[CROM DNA Decoder]\n")
sys.stderr.write(f" Codebook : {os.path.basename(caminho)}\n")
sys.stderr.write(f" Taxa : {taxa}\n")
sys.stderr.write(f" Modo : {modo}\n")
sys.stderr.write(f" Entradas : {len(entries)}\n")
sys.stderr.write(f" Escape : {escape}\n")
sys.stderr.write(f" βββββββββββββββββββββββββ\n")
sys.stderr.flush()
return entries, escape, taxa, modo
def decoder_streaming(entries, escape_prefix, max_buffer=10):
"""
Decodifica stream de tokens DNA do stdin.
Protocolo:
- Tokens sΓ£o separados por espaΓ§os ou newlines
- Tokens que comeΓ§am com o escape_prefix sΓ£o texto literal
- Tokens que existem no codebook sΓ£o expandidos
- Tokens desconhecidos sΓ£o marcados como [?token]
"""
stats = {
"tokens_recebidos": 0,
"tokens_validos": 0,
"tokens_escape": 0,
"tokens_alucinados": 0,
"palavras_emitidas": 0,
"t_inicio": time.time(),
"t_primeiro_token": None,
}
buffer = ""
for char in sys.stdin:
for c in char:
if c in (' ', '\n', '\t'):
if buffer:
_processar_token(buffer, entries, escape_prefix, stats)
buffer = ""
else:
buffer += c
# Safety: se buffer ficou muito grande, Γ© alucinaΓ§Γ£o
if len(buffer) > 20:
stats["tokens_alucinados"] += 1
stats["tokens_recebidos"] += 1
sys.stdout.write(f"[?{buffer}] ")
sys.stdout.flush()
buffer = ""
# Flush final
if buffer:
_processar_token(buffer, entries, escape_prefix, stats)
return stats
def _processar_token(token, entries, escape_prefix, stats):
"""Processa um token individual."""
stats["tokens_recebidos"] += 1
if stats["t_primeiro_token"] is None:
stats["t_primeiro_token"] = time.time()
# Modo escape: texto literal
if token.startswith(escape_prefix):
texto = token[len(escape_prefix):]
sys.stdout.write(texto + " ")
sys.stdout.flush()
stats["tokens_escape"] += 1
stats["palavras_emitidas"] += 1
return
# Lookup no codebook
if token in entries:
texto = entries[token]["text"]
n_palavras = entries[token].get("n", len(texto.split()))
sys.stdout.write(texto + " ")
sys.stdout.flush()
stats["tokens_validos"] += 1
stats["palavras_emitidas"] += n_palavras
return
# Token desconhecido (alucinaΓ§Γ£o)
sys.stdout.write(f"[?{token}] ")
sys.stdout.flush()
stats["tokens_alucinados"] += 1
def emitir_metricas(stats, taxa, modo, codebook_name):
"""Emite mΓ©tricas SRE no stderr."""
t_total = time.time() - stats["t_inicio"]
t_primeiro = (stats["t_primeiro_token"] - stats["t_inicio"]
if stats["t_primeiro_token"] else 0)
total = stats["tokens_recebidos"]
validos = stats["tokens_validos"]
escapes = stats["tokens_escape"]
alucinados = stats["tokens_alucinados"]
palavras = stats["palavras_emitidas"]
hit_rate = (validos / max(total, 1)) * 100
alucinacao = (alucinados / max(total, 1)) * 100
taxa_real = palavras / max(total, 1)
palavras_por_s = palavras / max(t_total, 0.001)
sys.stderr.write(f"\n")
sys.stderr.write(f"{'β' * 55}\n")
sys.stderr.write(f" [CROM DNA Decoder] RELATΓRIO FINAL\n")
sys.stderr.write(f"{'β' * 55}\n")
sys.stderr.write(f" Codebook : {codebook_name}\n")
sys.stderr.write(f" Taxa alvo : {taxa}\n")
sys.stderr.write(f" Modo : {modo}\n")
sys.stderr.write(f" βββββββββββββββββββββββββ\n")
sys.stderr.write(f" Tokens DNA in : {total}\n")
sys.stderr.write(f" Tokens vΓ‘lidos : {validos} ({hit_rate:.1f}%)\n")
sys.stderr.write(f" Tokens escape : {escapes}\n")
sys.stderr.write(f" Tokens alucinados : {alucinados} ({alucinacao:.1f}%)\n")
sys.stderr.write(f" βββββββββββββββββββββββββ\n")
sys.stderr.write(f" Palavras emitidas : {palavras}\n")
sys.stderr.write(f" Taxa real : 1:{taxa_real:.1f}\n")
sys.stderr.write(f" Velocidade : {palavras_por_s:.1f} palavras/s\n")
sys.stderr.write(f" LatΓͺncia 1ΒΊ token : {t_primeiro*1000:.0f} ms\n")
sys.stderr.write(f" Tempo total : {t_total:.2f} s\n")
sys.stderr.write(f"{'β' * 55}\n")
sys.stderr.flush()
def main():
parser = argparse.ArgumentParser(
description="𧬠CROM-IA V2: DNA Decoder Streaming"
)
parser.add_argument(
"--codebook", type=str, required=True,
help="Caminho para o codebook JSON"
)
parser.add_argument(
"--quiet", action="store_true",
help="Suprime mΓ©tricas no stderr"
)
args = parser.parse_args()
if not os.path.exists(args.codebook):
sys.stderr.write(f"β Codebook nΓ£o encontrado: {args.codebook}\n")
sys.exit(1)
entries, escape, taxa, modo = carregar_codebook(args.codebook)
try:
stats = decoder_streaming(entries, escape)
except KeyboardInterrupt:
stats = {"tokens_recebidos": 0, "tokens_validos": 0,
"tokens_escape": 0, "tokens_alucinados": 0,
"palavras_emitidas": 0, "t_inicio": time.time(),
"t_primeiro_token": None}
sys.stdout.write("\n")
sys.stdout.flush()
if not args.quiet:
emitir_metricas(stats, taxa, modo, os.path.basename(args.codebook))
if __name__ == "__main__":
main()
|