mrj-crom commited on
Commit
e306250
·
verified ·
1 Parent(s): 1a09ee9

sync: gerar_dataset_dna.py

Browse files
Files changed (1) hide show
  1. gerar_dataset_dna.py +190 -0
gerar_dataset_dna.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Módulo de Extração de Dados: FASE 1 - CROM-DNA LORA
4
+ Gera dataset_dna.jsonl no modo Híbrido Trifásico:
5
+ 33% Humano → DNA (codificação)
6
+ 33% DNA → Humano (decodificação)
7
+ 33% Contexto + DNA (instrução mista)
8
+
9
+ Preparado para upload direto ao Google Colab + Unsloth LoRA.
10
+ """
11
+
12
+ import os
13
+ import sys
14
+ import json
15
+ import math
16
+ import argparse
17
+ from collections import Counter
18
+
19
+ # ============================
20
+ # CROM Radix-4 DNA Engine
21
+ # ============================
22
+ DNA_MAP = {'00': 'A', '01': 'T', '10': 'C', '11': 'G'}
23
+ INV_DNA_MAP = {v: k for k, v in DNA_MAP.items()}
24
+
25
+ def txt_para_dna(texto):
26
+ """Destila bytes UTF-8 em sequências quaternárias A-T-C-G."""
27
+ dna_seq = []
28
+ for char in str(texto).encode('utf-8', errors='ignore'):
29
+ bits = format(char, '08b')
30
+ for i in range(0, 8, 2):
31
+ dna_seq.append(DNA_MAP[bits[i:i+2]])
32
+ return "".join(dna_seq)
33
+
34
+ def calcular_entropia(texto):
35
+ """Calcula entropia de Shannon H para uma string."""
36
+ if not texto:
37
+ return 0.0
38
+ contagem = Counter(texto.encode('utf-8', errors='ignore'))
39
+ total = sum(contagem.values())
40
+ entropia = 0.0
41
+ for count in contagem.values():
42
+ if count > 0:
43
+ p = count / total
44
+ entropia -= p * math.log2(p)
45
+ return entropia
46
+
47
+ def main():
48
+ parser = argparse.ArgumentParser(description="Gerador de Dataset DNA CROM para LoRA")
49
+ parser.add_argument("--amostras", type=int, default=10000, help="Total de amostras (default: 10000)")
50
+ parser.add_argument("--output", type=str, default=None, help="Caminho do arquivo de saída")
51
+ parser.add_argument("--max-entropia", type=float, default=7.0, help="Limiar máximo de entropia Shannon (default: 7.0)")
52
+ parser.add_argument("--max-chars", type=int, default=32768, help="Tamanho máximo instrução+output (default: 32768)")
53
+ args = parser.parse_args()
54
+
55
+ if args.output is None:
56
+ base_dir = os.path.dirname(os.path.abspath(__file__))
57
+ args.output = os.path.join(base_dir, "dataset_dna.jsonl")
58
+
59
+ print("=" * 55)
60
+ print(" 🧬 CROM-ENGINE: GERADOR DE DADOS TRIFÁSICO DNA")
61
+ print("=" * 55)
62
+ print(f" Amostras alvo : {args.amostras}")
63
+ print(f" Entropia máx : {args.max_entropia}")
64
+ print(f" Chars máx : {args.max_chars}")
65
+ print(f" Saída : {args.output}")
66
+ print("=" * 55)
67
+
68
+ print("\n[1] Baixando dataset Alpaca-PT do HuggingFace...")
69
+ try:
70
+ from datasets import load_dataset
71
+ dataset = load_dataset("FreedomIntelligence/alpaca-gpt4-portuguese", split="train")
72
+ except Exception as e:
73
+ print(f"\n[ERRO] Falha ao baixar dataset: {e}")
74
+ sys.exit(1)
75
+
76
+ TERCO = args.amostras // 3
77
+
78
+ print(f"\n[2] Processando {args.amostras} amostras em 3 fases...")
79
+ print(f" Fase A: {TERCO} Humano → DNA")
80
+ print(f" Fase B: {TERCO} DNA → Humano")
81
+ print(f" Fase C: {args.amostras - 2*TERCO} Contexto Misto")
82
+
83
+ dataset = dataset.shuffle(seed=42)
84
+ dados = []
85
+ stats = {"descartados_entropia": 0, "descartados_tamanho": 0, "descartados_vazio": 0}
86
+
87
+ idx = 0
88
+ for linha in dataset:
89
+ if len(dados) >= args.amostras:
90
+ break
91
+
92
+ convs = linha.get('conversations', [])
93
+ if not convs or len(convs) < 2:
94
+ stats["descartados_vazio"] += 1
95
+ continue
96
+
97
+ instrucao = ""
98
+ saida = ""
99
+
100
+ # Procura a primeira interação human/gpt
101
+ for c in convs:
102
+ if c.get("from") == "human" and not instrucao:
103
+ instrucao = str(c.get("value", "")).replace("\n", " ").strip()
104
+ elif c.get("from") == "gpt" and not saida:
105
+ saida = str(c.get("value", "")).replace("\n", " ").strip()
106
+
107
+ # Validação: campos vazios
108
+ if not instrucao or not saida:
109
+ stats["descartados_vazio"] += 1
110
+ continue
111
+
112
+ # Validação: tamanho
113
+ if len(instrucao) + len(saida) > args.max_chars:
114
+ stats["descartados_tamanho"] += 1
115
+ continue
116
+
117
+ # Validação: entropia Shannon
118
+ h_instrucao = calcular_entropia(instrucao)
119
+ h_saida = calcular_entropia(saida)
120
+ if h_instrucao > args.max_entropia or h_saida > args.max_entropia:
121
+ stats["descartados_entropia"] += 1
122
+ continue
123
+
124
+ fase = len(dados)
125
+
126
+ # FASE A: Humano pergunta, IA responde em DNA
127
+ if fase < TERCO:
128
+ dna_saida = txt_para_dna(saida)
129
+ obj = {
130
+ "instruction": "Você é uma Célula CROM. Transcreva a resposta como Cadeia Quaternária DNA CROM Base-4 (usar apenas A, T, C, G).",
131
+ "input": instrucao,
132
+ "output": dna_saida
133
+ }
134
+
135
+ # FASE B: Humano pergunta em DNA, IA decodifica para humano
136
+ elif fase < 2 * TERCO:
137
+ dna_pergunta = txt_para_dna(instrucao)
138
+ obj = {
139
+ "instruction": "Decodifique a sequência biológica DNA CROM Base-4 para linguagem humana em Português.",
140
+ "input": dna_pergunta,
141
+ "output": saida
142
+ }
143
+
144
+ # FASE C: Contexto misto (instrução humana + snippet DNA na entrada)
145
+ else:
146
+ dna_snippet = txt_para_dna(saida[:50])
147
+ obj = {
148
+ "instruction": "Analise o contexto abaixo. A primeira parte é linguagem humana. A segunda é uma amostra DNA CROM Radix-4. Responda o que for pedido em Português claro.",
149
+ "input": f"Contexto: {instrucao}\nAmostra DNA: {dna_snippet}",
150
+ "output": saida
151
+ }
152
+
153
+ dados.append(obj)
154
+ idx += 1
155
+
156
+ # Escrever JSONL
157
+ print(f"\n[3] Escrevendo {len(dados)} amostras em {args.output}...")
158
+ with open(args.output, 'w', encoding='utf-8') as f:
159
+ for obj in dados:
160
+ f.write(json.dumps(obj, ensure_ascii=False) + "\n")
161
+
162
+ # Estatísticas
163
+ tamanhos = [len(json.dumps(d, ensure_ascii=False)) for d in dados]
164
+ entropias = [calcular_entropia(d["output"]) for d in dados]
165
+ arquivo_mb = os.path.getsize(args.output) / 1024 / 1024
166
+
167
+ if len(dados) > 0:
168
+ linha_media = sum(tamanhos) / len(tamanhos)
169
+ entropia_media = sum(entropias) / len(entropias)
170
+ else:
171
+ linha_media = 0
172
+ entropia_media = 0
173
+
174
+ print("\n" + "=" * 55)
175
+ print(" ✅ DATASET GERADO COM SUCESSO!")
176
+ print("=" * 55)
177
+ print(f" 📊 Amostras geradas : {len(dados)}")
178
+ print(f" 📁 Arquivo : {args.output}")
179
+ print(f" 💾 Tamanho : {arquivo_mb:.1f} MB")
180
+ print(f" 📏 Linha média : {linha_media:.0f} chars")
181
+ print(f" 🧬 Entropia média output : {entropia_media:.2f}")
182
+ print(f" ❌ Descartados entropia : {stats['descartados_entropia']}")
183
+ print(f" ❌ Descartados tamanho : {stats['descartados_tamanho']}")
184
+ print(f" ❌ Descartados vazios : {stats['descartados_vazio']}")
185
+ print("=" * 55)
186
+ print("\n🚀 Próximo passo: Suba dataset_dna.jsonl no Google Colab")
187
+ print(" e execute o script de treinamento LoRA!")
188
+
189
+ if __name__ == "__main__":
190
+ main()