PowerMachine commited on
Commit
961ff8b
·
verified ·
1 Parent(s): f387c2d

Delete cnn_bigru/data/streaming_dataset.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. cnn_bigru/data/streaming_dataset.py +0 -308
cnn_bigru/data/streaming_dataset.py DELETED
@@ -1,308 +0,0 @@
1
- """streaming_dataset.py — Carregador de dataset streaming para o CNN-BiGRU.
2
-
3
- Adaptado de xavante_work/flexnet/streaming_datasets_v13_9.py, com:
4
- - Modo streaming (IterableDataset, sem materialização completa)
5
- - Fallback sintético quando datasets externos estão indisponíveis
6
- - Suporte multimodal: texto + imagem (placeholder) + áudio (placeholder)
7
- - Garantia de produzir N amostras para o teste de 50 samples
8
-
9
- Para o projeto CNN-BiGRU, usamos um gerador sintético multi-modal padrão
10
- quando a rede ou HF não está acessível, garantindo que o teste de 50 amostras
11
- sempre execute.
12
- """
13
- from __future__ import annotations
14
-
15
- import logging
16
- import os
17
- import random
18
- from dataclasses import dataclass, field
19
- from typing import Any, Dict, Iterator, List, Optional, Sequence
20
-
21
- import numpy as np
22
- import torch
23
-
24
- logger = logging.getLogger(__name__)
25
-
26
-
27
- @dataclass
28
- class MultimodalSample:
29
- """Amostra multimodal: texto + imagem (HxWxC float) + áudio (spec TxF)."""
30
- sample_id: int
31
- text_a: str # Stream A (e.g. pergunta/título)
32
- text_b: str # Stream B (e.g. contexto/corpo)
33
- image: Optional[np.ndarray] = None # [H, W, C] float32 in [0,1]
34
- audio: Optional[np.ndarray] = None # [T, F] spectrogram float32
35
- label: int = 0
36
- metadata: Dict[str, Any] = field(default_factory=dict)
37
-
38
-
39
- # Dataset padrão V13.9.1 (mesmos do reference streaming_datasets_v13_9.py)
40
- DEFAULT_DATASETS = [
41
- "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
42
- "Madras1/corpus-ptbr-v2",
43
- "rhaymison/multmodal_175k_portuguese",
44
- "TucanoBR/GigaVerbo",
45
- "nvidia/OpenMathReasoning",
46
- "MathLLMs/MathVision",
47
- "nvidia/OpenMathInstruct-2",
48
- "dominguesm/restore-punctuation-ptbr-dataset",
49
- "carolina-c4ai/corpus-carolina",
50
- ]
51
-
52
-
53
- def _extract_field(sample: Dict[str, Any], candidates: List[str]) -> Optional[str]:
54
- for f in candidates:
55
- if f in sample:
56
- v = sample[f]
57
- if isinstance(v, str) and v.strip():
58
- return v
59
- if isinstance(v, list):
60
- parts = []
61
- for m in v:
62
- if isinstance(m, dict):
63
- c = m.get("content", "")
64
- if isinstance(c, str) and c.strip():
65
- parts.append(c)
66
- elif isinstance(m, str) and m.strip():
67
- parts.append(m)
68
- if parts:
69
- return "\n".join(parts)
70
- return None
71
-
72
-
73
- def _try_load_hf_streaming(
74
- dataset_name: str,
75
- split: str = "train",
76
- hf_token: Optional[str] = None,
77
- ):
78
- """Tenta carregar dataset HF em streaming. Retorna None se falhar."""
79
- try:
80
- from datasets import load_dataset
81
- ds = load_dataset(dataset_name, split=split, streaming=True, token=hf_token)
82
- logger.info("Streaming OK: %s[%s]", dataset_name, split)
83
- return ds
84
- except Exception as e:
85
- logger.info("Streaming falhou para %s: %s", dataset_name, str(e)[:120])
86
- return None
87
-
88
-
89
- def synthetic_multimodal_stream(
90
- n_samples: int,
91
- seed: int = 42,
92
- image_size: tuple = (28, 28, 1),
93
- audio_shape: tuple = (64, 40),
94
- vocab_texts: Optional[Sequence[str]] = None,
95
- ) -> Iterator[MultimodalSample]:
96
- """Gera amostras sintéticas multimodais determinísticas.
97
-
98
- Usado quando o dataset HF está indisponível (offline, rate-limit, etc.).
99
- Garante que o teste de 50 amostras sempre execute.
100
- """
101
- rng = random.Random(seed)
102
- np_rng = np.random.RandomState(seed)
103
-
104
- if vocab_texts is None:
105
- vocab_texts = [
106
- "o modelo aprende padrões locais com convoluções",
107
- "a ponte de cooperação troca informações entre fluxos",
108
- "grus capturam dependências temporais bidirecionais",
109
- "atenção cruzada reduz perplexidade em textos longos",
110
- "a fusão multimodal combina texto imagem e áudio",
111
- "penalidades evitam repetições viciosas na geração",
112
- "a camada anti-alucinação usa lógica fuzzy de lukasiewicz",
113
- "o verificador classifica passos com sigmoid binária",
114
- "ajustes dinâmicos de lr controlam explosão de gradiente",
115
- "normalização espectral estabiliza o treinamento",
116
- ]
117
-
118
- n_vocab = len(vocab_texts)
119
- for i in range(n_samples):
120
- text_a = vocab_texts[rng.randrange(n_vocab)]
121
- text_b = vocab_texts[rng.randrange(n_vocab)]
122
- # Imagem sintética: padrões estruturados simples
123
- img = np_rng.rand(*image_size).astype(np.float32)
124
- # Adiciona um padrão que depende do índice (para discriminação)
125
- img[i % image_size[0], :, :] = 1.0
126
- # Áudio sintético: espectrograma
127
- aud = np_rng.rand(*audio_shape).astype(np.float32) * 0.5
128
- # Espectro com picos determinísticos
129
- aud[i % audio_shape[0], :] += 0.5
130
- yield MultimodalSample(
131
- sample_id=i,
132
- text_a=text_a,
133
- text_b=text_b,
134
- image=img,
135
- audio=aud,
136
- label=i % 3,
137
- metadata={"source": "synthetic", "idx": i},
138
- )
139
-
140
-
141
- class MultimodalStreamingDataset(torch.utils.data.IterableDataset):
142
- """Dataset streaming multimodal. Suporta HF + fallback sintético.
143
-
144
- Args:
145
- n_samples: número total de amostras a produzir.
146
- hf_datasets: lista de datasets HF para tentar (em ordem).
147
- hf_token: token HF (será limpo após uso).
148
- use_synthetic_fallback: se True, usa sintético quando HF falha.
149
- seed: seed para reprodutibilidade.
150
- """
151
-
152
- def __init__(
153
- self,
154
- n_samples: int = 50,
155
- hf_datasets: Optional[List[str]] = None,
156
- hf_token: Optional[str] = None,
157
- use_synthetic_fallback: bool = True,
158
- seed: int = 42,
159
- image_size: tuple = (28, 28, 1),
160
- audio_shape: tuple = (64, 40),
161
- ):
162
- super().__init__()
163
- self.n_samples = n_samples
164
- self.hf_datasets = hf_datasets or DEFAULT_DATASETS
165
- self.hf_token = hf_token
166
- self.use_synthetic_fallback = use_synthetic_fallback
167
- self.seed = seed
168
- self.image_size = image_size
169
- self.audio_shape = audio_shape
170
-
171
- def _try_hf(self) -> Iterator[Dict[str, Any]]:
172
- """Tenta carregar amostras HF. Retorna iterator vazio se falhar."""
173
- for ds_name in self.hf_datasets:
174
- ds = _try_load_hf_streaming(ds_name, split="train", hf_token=self.hf_token)
175
- if ds is None:
176
- continue
177
- count = 0
178
- text_candidates = ["text", "content", "question", "problem", "input",
179
- "conversa", "description", "prompt", "instruction"]
180
- label_candidates = ["answer", "response", "output", "solution",
181
- "punctuated", "restored"]
182
- for raw in ds:
183
- if count >= self.n_samples:
184
- break
185
- try:
186
- text_a = _extract_field(raw, text_candidates) or ""
187
- text_b = _extract_field(raw, label_candidates) or ""
188
- if len(text_a) < 5:
189
- text_a = "pergunta de exemplo sobre o tema"
190
- if len(text_b) < 5:
191
- text_b = "resposta de exemplo para contexto"
192
- # Image/audio placeholder: geramos sintéticos para manter multimodal
193
- img = np.random.rand(*self.image_size).astype(np.float32) * 0.5
194
- aud = np.random.rand(*self.audio_shape).astype(np.float32) * 0.5
195
- yield {
196
- "sample_id": count,
197
- "text_a": text_a[:200], # truncado para teste
198
- "text_b": text_b[:200],
199
- "image": img,
200
- "audio": aud,
201
- "label": count % 3,
202
- "metadata": {"source": ds_name, "idx": count},
203
- }
204
- count += 1
205
- except Exception as e:
206
- logger.debug("skip sample %d from %s: %s", count, ds_name, e)
207
- continue
208
- if count > 0:
209
- logger.info("HF yield %d samples de %s", count, ds_name)
210
- return
211
-
212
- def __iter__(self) -> Iterator[Dict[str, Any]]:
213
- # Tentar HF primeiro
214
- if self.hf_datasets:
215
- try:
216
- yield from self._try_hf()
217
- return
218
- except Exception as e:
219
- logger.warning("HF streaming falhou (%s) — usando fallback sintético", e)
220
-
221
- # Fallback sintético
222
- if self.use_synthetic_fallback:
223
- for s in synthetic_multimodal_stream(
224
- n_samples=self.n_samples,
225
- seed=self.seed,
226
- image_size=self.image_size,
227
- audio_shape=self.audio_shape,
228
- ):
229
- yield {
230
- "sample_id": s.sample_id,
231
- "text_a": s.text_a,
232
- "text_b": s.text_b,
233
- "image": s.image,
234
- "audio": s.audio,
235
- "label": s.label,
236
- "metadata": s.metadata,
237
- }
238
-
239
-
240
- def collate_multimodal(
241
- batch: List[Dict[str, Any]],
242
- tokenizer,
243
- max_len: int = 64,
244
- ) -> Dict[str, torch.Tensor]:
245
- """Cola um batch de amostras multimodais em tensores.
246
-
247
- Returns dict com:
248
- input_ids_a: [B, T] (stream A)
249
- input_ids_b: [B, T] (stream B)
250
- attn_mask_a: [B, T]
251
- attn_mask_b: [B, T]
252
- images: [B, C, H, W]
253
- audios: [B, 1, T, F]
254
- labels: [B]
255
- """
256
- texts_a = [b["text_a"] for b in batch]
257
- texts_b = [b["text_b"] for b in batch]
258
- ids_a = tokenizer.encode_batch(texts_a, add_special=True)
259
- ids_b = tokenizer.encode_batch(texts_b, add_special=True)
260
-
261
- pad_id = tokenizer.pad_id
262
-
263
- def _pad(seqs, max_len):
264
- out = []
265
- masks = []
266
- for s in seqs:
267
- s = s[:max_len]
268
- n = len(s)
269
- padded = s + [pad_id] * (max_len - n)
270
- mask = [1] * n + [0] * (max_len - n)
271
- out.append(padded)
272
- masks.append(mask)
273
- return out, masks
274
-
275
- padded_a, masks_a = _pad(ids_a, max_len)
276
- padded_b, masks_b = _pad(ids_b, max_len)
277
-
278
- images = np.stack([b["image"] for b in batch]) # [B, H, W, C]
279
- # converte para [B, C, H, W]
280
- if images.ndim == 4:
281
- images = np.transpose(images, (0, 3, 1, 2))
282
- else:
283
- images = images[:, None, :, :] # add channel dim
284
-
285
- audios = np.stack([b["audio"] for b in batch]) # [B, T, F]
286
- audios = audios[:, None, :, :] # [B, 1, T, F]
287
-
288
- labels = np.array([b["label"] for b in batch], dtype=np.int64)
289
-
290
- return {
291
- "input_ids_a": torch.tensor(padded_a, dtype=torch.long),
292
- "input_ids_b": torch.tensor(padded_b, dtype=torch.long),
293
- "attn_mask_a": torch.tensor(masks_a, dtype=torch.float),
294
- "attn_mask_b": torch.tensor(masks_b, dtype=torch.float),
295
- "images": torch.tensor(images, dtype=torch.float32),
296
- "audios": torch.tensor(audios, dtype=torch.float32),
297
- "labels": torch.tensor(labels, dtype=torch.long),
298
- "sample_ids": [b["sample_id"] for b in batch],
299
- }
300
-
301
-
302
- __all__ = [
303
- "MultimodalSample",
304
- "MultimodalStreamingDataset",
305
- "collate_multimodal",
306
- "DEFAULT_DATASETS",
307
- "synthetic_multimodal_stream",
308
- ]