jmpicon2026 commited on
Commit
fd1a4cc
·
verified ·
1 Parent(s): ee2ff33

docs(README): instrucciones de instalación completas (Ollama / llama.cpp / Transformers+LoRA) + troubleshooting + RAG pattern

Browse files
Files changed (1) hide show
  1. README.md +219 -11
README.md CHANGED
@@ -72,39 +72,247 @@ NO destinado para:
72
  - Análisis forense sin contexto RAG (el modelo se apoya fuertemente en
73
  hallazgos recuperados; las respuestas standalone son más débiles).
74
 
75
- ## Cómo usar
76
 
77
- ### Con Ollama (recomendado para despliegue VPS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  ```bash
80
- # Importa el GGUF Q4_K_M desde el archivo local
81
  ollama create darkforensic-7b -f Modelfile
 
 
 
 
82
 
83
- # Ejemplo
84
- ollama run darkforensic-7b "¿Qué hacer si detectamos credenciales nuestras en un combo-list?"
 
85
  ```
86
 
87
- ### Con Transformers + LoRA (inferencia HF)
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  ```python
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  from transformers import AutoModelForCausalLM, AutoTokenizer
91
  from peft import PeftModel
92
 
 
93
  base = AutoModelForCausalLM.from_pretrained(
94
- "Qwen/Qwen2.5-7B-Instruct", torch_dtype="bfloat16", device_map="auto"
 
 
95
  )
96
  model = PeftModel.from_pretrained(base, "neuralghost/darkforensic-7b")
97
  tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
98
 
99
  messages = [
100
  {"role": "system", "content": "Eres darkforensic, asistente threat-intel..."},
101
- {"role": "user", "content": "..."},
102
  ]
103
- inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to(model.device)
104
- out = model.generate(inputs, max_new_tokens=300)
105
- print(tokenizer.decode(out[0], skip_special_tokens=True))
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  ```
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  ## Detalles del entrenamiento
109
 
110
  | | |
 
72
  - Análisis forense sin contexto RAG (el modelo se apoya fuertemente en
73
  hallazgos recuperados; las respuestas standalone son más débiles).
74
 
75
+ ## Cómo instalar y ejecutar darkforensic-7b en local
76
 
77
+ Hay tres formas, según tu hardware. Si no sabes cuál elegir, usa la
78
+ **Opción A (Ollama)**: es la más rápida y funciona en cualquier laptop
79
+ con 8 GB de RAM o más.
80
+
81
+ ### Requisitos por opción
82
+
83
+ | Opción | RAM mínima | GPU | Disco | Velocidad típica |
84
+ |---|---|---|---|---|
85
+ | A. Ollama (Q4_K_M) | 8 GB | no necesaria | ~5 GB | 5–15 tok/s en CPU; 30–60 con GPU |
86
+ | B. llama.cpp (Q4_K_M) | 8 GB | no necesaria | ~5 GB | igual que Ollama, sin server |
87
+ | C. Transformers + LoRA | 24 GB GPU | sí, A100/H100 ideal | ~16 GB | 20–40 tok/s en H100 |
88
+
89
+ ---
90
+
91
+ ### Opción A — Ollama (recomendada)
92
+
93
+ Funciona en Linux, macOS, Windows. Es lo que usamos en producción en el
94
+ VPS de Neural Ghost.
95
+
96
+ **1. Instala Ollama** (1 comando):
97
+
98
+ ```bash
99
+ # Linux / macOS
100
+ curl -fsSL https://ollama.com/install.sh | sh
101
+
102
+ # Windows: descarga el instalador desde https://ollama.com/download
103
+ ```
104
+
105
+ Verifica que está instalado:
106
+
107
+ ```bash
108
+ ollama --version # debe imprimir "ollama version is X.Y.Z"
109
+ ```
110
+
111
+ **2. Descarga el GGUF Q4_K_M y el Modelfile** de este repo:
112
+
113
+ ```bash
114
+ mkdir darkforensic && cd darkforensic
115
+
116
+ # Descarga el modelo (4.7 GB) y el Modelfile
117
+ curl -L -o darkforensic-7b-v2-q4_k_m.gguf \
118
+ https://huggingface.co/neuralghost/darkforensic-7b/resolve/main/darkforensic-7b-v2-q4_k_m.gguf
119
+ curl -L -o Modelfile \
120
+ https://huggingface.co/neuralghost/darkforensic-7b/raw/main/Modelfile
121
+ ```
122
+
123
+ (Alternativa: con `huggingface-cli download neuralghost/darkforensic-7b` —
124
+ te baja todo el repo de golpe. Más cómodo si tienes la CLI instalada.)
125
+
126
+ **3. Importa el modelo a Ollama**:
127
 
128
  ```bash
 
129
  ollama create darkforensic-7b -f Modelfile
130
+ ```
131
+
132
+ Esto tarda 30 s – 2 min la primera vez (Ollama indexa el GGUF y lo deja
133
+ listo). Verifica que está:
134
 
135
+ ```bash
136
+ ollama list
137
+ # debe aparecer "darkforensic-7b" con el tag latest
138
  ```
139
 
140
+ **4. Pruébalo**:
141
+
142
+ ```bash
143
+ ollama run darkforensic-7b "Hemos detectado credenciales de empleados \
144
+ nuestros en un combo-list publicado en RaidForums. ¿Qué hago en las \
145
+ próximas 24 horas?"
146
+ ```
147
+
148
+ Te debería responder en castellano con un plan estructurado:
149
+ resumen → acciones inmediatas → IOCs → marco regulatorio (RGPD/NIS2).
150
+
151
+ **5. Para usarlo desde tu aplicación** (Python, etc.) — Ollama expone una
152
+ API REST en `http://localhost:11434`:
153
 
154
  ```python
155
+ import httpx, json
156
+
157
+ resp = httpx.post(
158
+ "http://localhost:11434/api/generate",
159
+ json={
160
+ "model": "darkforensic-7b",
161
+ "prompt": "Pregunta operativa CISO/DPO aquí…",
162
+ "stream": False,
163
+ },
164
+ timeout=120,
165
+ )
166
+ print(resp.json()["response"])
167
+ ```
168
+
169
+ **6. Detenerlo / liberar memoria** cuando no lo uses:
170
+
171
+ ```bash
172
+ ollama stop darkforensic-7b
173
+ ```
174
+
175
+ ---
176
+
177
+ ### Opción B — llama.cpp (sin servidor, ideal si quieres scriptear)
178
+
179
+ Si prefieres no levantar el daemon de Ollama, puedes cargar el GGUF
180
+ directamente con `llama.cpp`:
181
+
182
+ ```bash
183
+ # Instalar llama-cpp-python con soporte CUDA (omite CMAKE_ARGS si no tienes GPU)
184
+ CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python --upgrade --force-reinstall --no-cache-dir
185
+ ```
186
+
187
+ Y úsalo así desde Python:
188
+
189
+ ```python
190
+ from llama_cpp import Llama
191
+
192
+ llm = Llama(
193
+ model_path="darkforensic-7b-v2-q4_k_m.gguf",
194
+ n_ctx=8192,
195
+ n_gpu_layers=-1, # -1 = todas las capas en GPU; 0 = solo CPU
196
+ chat_format="chatml", # Qwen2.5 usa ChatML
197
+ )
198
+
199
+ response = llm.create_chat_completion(
200
+ messages=[
201
+ {"role": "system", "content":
202
+ "Eres darkforensic, asistente threat-intel dark-web para CISOs/DPOs "
203
+ "europeos. Responde en castellano, conciso, con acciones operativas y "
204
+ "el marco regulatorio (RGPD/NIS2/DORA) si aplica."},
205
+ {"role": "user", "content":
206
+ "¿Qué IOCs debo extraer de este finding y cómo los cruzo con mi SIEM?"},
207
+ ],
208
+ temperature=0.3,
209
+ max_tokens=1024,
210
+ )
211
+ print(response["choices"][0]["message"]["content"])
212
+ ```
213
+
214
+ ---
215
+
216
+ ### Opción C — Transformers + LoRA (necesitas GPU)
217
+
218
+ Esta opción carga el **modelo base** (Qwen2.5-7B-Instruct, ~16 GB en
219
+ bfloat16) **y aplica el LoRA adapter encima** (162 MB). Útil si quieres
220
+ seguir entrenando, mergear con otro adapter, o tener máxima precisión.
221
+
222
+ **1. Instalar dependencias**:
223
+
224
+ ```bash
225
+ pip install transformers peft accelerate bitsandbytes torch
226
+ ```
227
+
228
+ **2. Cargar y usar**:
229
+
230
+ ```python
231
+ import torch
232
  from transformers import AutoModelForCausalLM, AutoTokenizer
233
  from peft import PeftModel
234
 
235
+ # Base model en bf16 (16 GB VRAM) — o en 4-bit con bnb si tienes menos
236
  base = AutoModelForCausalLM.from_pretrained(
237
+ "Qwen/Qwen2.5-7B-Instruct",
238
+ torch_dtype=torch.bfloat16,
239
+ device_map="auto",
240
  )
241
  model = PeftModel.from_pretrained(base, "neuralghost/darkforensic-7b")
242
  tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
243
 
244
  messages = [
245
  {"role": "system", "content": "Eres darkforensic, asistente threat-intel..."},
246
+ {"role": "user", "content": "Tu pregunta aquí"},
247
  ]
248
+ inputs = tokenizer.apply_chat_template(
249
+ messages, return_tensors="pt", add_generation_prompt=True
250
+ ).to(model.device)
251
+ out = model.generate(inputs, max_new_tokens=600, do_sample=True, temperature=0.3)
252
+ print(tokenizer.decode(out[0][inputs.shape[-1]:], skip_special_tokens=True))
253
+ ```
254
+
255
+ **Si tienes menos de 24 GB de VRAM** — carga el base en 4-bit:
256
+
257
+ ```python
258
+ from transformers import BitsAndBytesConfig
259
+ bnb = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
260
+ base = AutoModelForCausalLM.from_pretrained(
261
+ "Qwen/Qwen2.5-7B-Instruct", quantization_config=bnb, device_map="auto",
262
+ )
263
+ # (el resto igual)
264
  ```
265
 
266
+ Con 4-bit cabe en ~6 GB de VRAM (RTX 3060 12 GB, RTX 4060 8 GB con stretching).
267
+
268
+ ---
269
+
270
+ ## Troubleshooting
271
+
272
+ | Síntoma | Causa probable | Solución |
273
+ |---|---|---|
274
+ | `ollama create` se queda colgado | El Modelfile referencia un GGUF que no existe en esa carpeta | Verifica que `darkforensic-7b-v2-q4_k_m.gguf` está en el mismo directorio que el `Modelfile` |
275
+ | `Error: out of memory` al usarlo | Estás cargando fp16/bf16 en GPU pequeña, o varios modelos a la vez en Ollama | Usa Q4_K_M; `ollama stop` los otros modelos; o reduce `num_ctx` en el Modelfile (8192 → 4096) |
276
+ | Respuestas muy lentas (< 2 tok/s) | Corriendo en CPU sin AVX2, o el modelo no cabe en RAM y está paginando a disco | Verifica `grep avx2 /proc/cpuinfo`; baja a 4 hilos con `OLLAMA_NUM_PARALLEL=1`; cierra otras apps con memoria pesada |
277
+ | Responde en inglés cuando le hablas en castellano | Faltó el system prompt o el primer mensaje es muy corto | Asegúrate de pasar el system del Modelfile (Ollama lo aplica automáticamente con `ollama run`); con la API REST mándalo explícito |
278
+ | "Permission denied" al ejecutar | Falta permisos en `~/.ollama` | `chmod -R u+rw ~/.ollama` |
279
+ | El modelo alucina IOCs específicos (BTC addresses, hashes) | El modelo describe IOCs, NO los memoriza — por diseño | Es el comportamiento correcto, no un bug. Para IOCs verbatim necesitas el RAG sobre tu corpus indexado, no el LLM solo |
280
+
281
+ ## Integración con un pipeline RAG (recomendado para producción)
282
+
283
+ DarkForensic-7B está pensado para responder **con contexto recuperado** de
284
+ tu propio corpus de hallazgos. Sin RAG es un asistente; con RAG es una
285
+ herramienta de análisis. El patrón básico:
286
+
287
+ ```python
288
+ # 1. El usuario pregunta algo sobre un finding
289
+ question = "¿Cómo respondo a este leak de credenciales?"
290
+
291
+ # 2. Tu sistema RAG recupera los k findings más relevantes del corpus
292
+ context_findings = your_rag.retrieve(question, k=5)
293
+ context_text = "\n\n".join(
294
+ f"[finding {f.id}] {f.title}\n{f.snippet}" for f in context_findings
295
+ )
296
+
297
+ # 3. Se manda al modelo en el system o como contexto previo
298
+ prompt = f"""CONTEXTO (5 findings relevantes de tu corpus dark-web):
299
+ {context_text}
300
+
301
+ PREGUNTA DEL ANALISTA: {question}
302
+
303
+ Responde citando los finding IDs cuando uses información de ellos.
304
+ Si los findings no contienen información suficiente, dilo explícitamente."""
305
+
306
+ # 4. Llama al modelo (Ollama u otro)
307
+ response = httpx.post("http://localhost:11434/api/generate",
308
+ json={"model": "darkforensic-7b", "prompt": prompt, "stream": False},
309
+ timeout=120).json()["response"]
310
+ ```
311
+
312
+ La plataforma completa que envuelve esto (crawler Tor/I2P, scoring,
313
+ RAG vectorial, alertas, UI) es **GhostNet Intelligence Platform** y se
314
+ comercializa por separado. Contacto: hello@neural-ghost.com.
315
+
316
  ## Detalles del entrenamiento
317
 
318
  | | |