neuronal / engine /include /brain.h
amogaddy's picture
amogaddyofficial
claude sonnet 4.6
Neuronal
d601f7c
Raw History Blame Contribute Delete
8.76 kB
// Brain: il modello linguistico con i suoi neuroni reali esposti.
// Osserva le attivazioni FFN (ffn_swiglu-L) di ogni strato durante il calcolo e applica
// gli interventi (spegnimento / amplificazione) prima che il resto della rete le legga.
#pragma once
#include <stdbool.h>
#include <stddef.h>
typedef struct Brain Brain;
typedef struct {
int n_layer;
int n_ff; // neuroni FFN per strato
long n_neurons; // n_layer * n_ff
int n_embd; // dimensione del flusso residuo
} BrainInfo;
// Area creata (neurogenesi): neuroni aggiunti alla rete, calcolati dentro il modello.
// Il neurone k legge l'ingresso FFN x del suo strato e, se si attiva, scrive nell'uscita FFN:
// a = tonic ? 1 : clamp((w_in·x - bias) * scale, 0, 1) uscita += gain * a * w_out
typedef struct {
int n; // neuroni
int *layer; // [n]
float *w_in; // [n][n_embd]
float *bias, *scale; // [n]
float *w_out; // [n][n_embd]
float gain;
bool enabled, tonic;
} BrainArea;
typedef enum { ROLE_SYSTEM, ROLE_USER, ROLE_ASSISTANT } Role;
// Perché si è fermata l'ultima generazione.
typedef enum { STOP_END, STOP_MAX, STOP_LOOP, STOP_USER } BrainStop;
typedef struct { Role role; const char *text; } ChatMsg;
typedef struct {
bool thinking; // ragionamento attivo
int think_budget; // massimo token di ragionamento (<= 0: nessun limite)
int max_tokens; // massimo token totali generati
float temperature; // <= 0: greedy (deterministico)
unsigned seed;
float repeat_penalty; // > 1 penalizza i token recenti (contro i loop); 0 o 1 = spenta
bool tools; // strumenti attivi: si ferma dopo </tool_call> e non scambia il codice per un loop
const unsigned char *image_rgb; // immagine allegata all'ultimo messaggio dell'utente (RGB, 3 byte per pixel)
int image_w, image_h;
} GenOpts;
// Chiamata per ogni frammento generato. thought = parte del ragionamento.
// Ritorna false per interrompere la generazione.
typedef bool (*brain_token_fn)(void *ud, const char *piece, bool thought);
// backend_dir: cartella con ggml-cuda.dll e ggml-cpu-*.dll (NULL = cartella dell'eseguibile).
// n_gpu_layers: strati caricati sulla GPU (999 = tutti).
Brain *brain_open(const char *model_path, int n_ctx, const char *backend_dir, int n_gpu_layers);
void brain_close(Brain *b);
// Visione: carica il proiettore delle immagini (neuronal-visione.gguf). Si chiama una volta; true se pronta.
bool brain_vision_open(Brain *b, const char *mmproj_path);
bool brain_has_vision(const Brain *b);
BrainInfo brain_info(const Brain *b);
// Attivazione dell'ultimo token calcolato: [n_layer][n_ff].
const float *brain_last_activation(const Brain *b);
// Accumulo di |a| per neurone su tutti i token calcolati tra begin e end (per la mappatura).
void brain_accum_begin(Brain *b);
const double *brain_accum(const Brain *b, long *n_tokens); // [n_layer][n_ff]
void brain_accum_end(Brain *b);
// Fa "leggere" un testo al modello senza generare. Ritorna i token letti o -1.
int brain_feed(Brain *b, const char *text);
// Conversazione. Ritorna i token generati o -1. answer riceve la risposta (senza ragionamento).
int brain_chat(Brain *b, const ChatMsg *msgs, int n_msgs, const GenOpts *opts,
brain_token_fn fn, void *ud, char *answer, size_t answer_cap);
// Interventi sui neuroni. factor: 0 = spento, 1 = normale, >1 amplificato, <0 invertito.
// Ogni chiamata è un'operazione annullabile. Ritorna il numero di neuroni modificati o -1.
int brain_set_neurons(Brain *b, int layer, const int *idx, int n, float factor);
// I k neuroni più attivi (|a|) dello strato, dall'ultima attivazione. Ritorna quanti.
// Da chiamare dal thread che esegue il modello (l'attivazione cambia durante il calcolo).
int brain_top_neurons(const Brain *b, int layer, int k, int *out);
// Indici dei k valori più grandi in modulo di a[0..n), in ordine decrescente. Ritorna quanti.
int top_abs(const float *a, int n, int k, int *out);
bool brain_undo(Brain *b);
void brain_reset(Brain *b);
// Neuroni modificati per strato (array di n_layer elementi). Ritorna il totale.
long brain_intervention_counts(Brain *b, int *per_layer);
float brain_neuron_factor(Brain *b, int layer, int idx);
// Elenco dei neuroni modificati (fino a cap). Ritorna quanti ne ha scritti.
int brain_intervention_list(Brain *b, int *layer, int *idx, float *factor, int cap);
// Autodiagnosi: sospende o riattiva tutti gli interventi manuali senza perderli.
void brain_interventions_enable(Brain *b, bool on);
BrainStop brain_last_stop(const Brain *b);
// Modifiche strutturali (macroaree eliminate o riconvertite): si sommano agli interventi ma non
// fanno parte di annulla/ripristina. idx NULL = tutti i neuroni dello strato. Ritorna quanti o -1.
int brain_struct_set(Brain *b, int layer, const int *idx, int n, float factor);
void brain_struct_clear(Brain *b);
// Esercitazione di infezione: fattore separato da tutto il resto (1 = sano). Ritorna true se è cambiato.
bool brain_infect_set(Brain *b, int layer, int idx, float factor);
float brain_infect_get(Brain *b, int layer, int idx);
void brain_infect_clear(Brain *b); // anche i neuroni delle aree
// Infezione di un neurone di un'area creata (k = indice nell'area). Ritorna true se è cambiato.
bool brain_area_infect(Brain *b, int id, int k, float factor);
// Attività media dei neuroni dell'area nell'ultimo accumulo (brain_accum_begin/end). Ritorna quanti o -1.
int brain_area_accum(Brain *b, int id, float *out, int cap);
// Cattura: somma per strato dell'ingresso FFN (x) e dell'uscita dello strato (l_out) su tutti i token.
void brain_capture_begin(Brain *b);
const double *brain_capture_x(const Brain *b, long *n_tokens); // [n_layer][n_embd]
const double *brain_capture_out(const Brain *b); // [n_layer][n_embd]
const float *brain_capture_last(const Brain *b); // [n_layer][n_embd] ingresso FFN dell'ultimo token
void brain_capture_end(Brain *b);
// Aree create. id scelto dal chiamante (stabile tra gli avvii). La brain copia i dati.
bool brain_area_add(Brain *b, int id, const BrainArea *a);
bool brain_area_update(Brain *b, int id, bool enabled, float gain);
bool brain_area_remove(Brain *b, int id);
// Attivazioni dell'ultimo token dei neuroni dell'area (fino a cap). Ritorna quanti o -1.
int brain_area_activation(Brain *b, int id, float *out, int cap);
// ---- Calcolo delegato ---------------------------------------------------------------------------------
// Lettura e generazione possono girare in un altro processo, su una GPU presa in prestito per pochi secondi.
// Interventi, aree e ogni dato letto dal programma restano qui: prima del calcolo viaggia lo stato dei neuroni,
// dopo tornano le attivazioni. Se il collegamento manca o cade si calcola qui, come sempre.
typedef struct {
void *ud;
// C'è un cervello remoto con almeno need_s secondi a disposizione? 1 sì, 0 no, -1 c'è ma il tempo non basta.
// request: se non c'è lo chiede e aspetta un po'.
int (*acquire)(void *ud, int need_s, bool request);
unsigned (*epoch)(void *ud); // cambia a ogni nuovo cervello remoto (mai 0)
bool (*send)(void *ud, const void *data, size_t len);
// Blocco ricevuto (da liberare) o NULL se è caduto o il tempo è scaduto. timeout_ms: 0 = solo se c'è già, < 0 = senza limite.
void *(*recv)(void *ud, size_t *len, int timeout_ms);
void (*drop)(void *ud); // chiude il collegamento
} BrainLink;
void brain_link_set(Brain *b, const BrainLink *l);
// Da chiamare ogni tanto da un altro thread: se il cervello remoto è fermo da idle_s secondi (o il suo tempo
// sta finendo) recupera i dati rimasti di là e lo congeda, così la GPU torna libera.
void brain_link_idle(Brain *b, double idle_s);
// Lato remoto: serve le richieste finché arriva il congedo o cade il collegamento (usa send e recv).
void brain_serve(Brain *b, const BrainLink *l, const char *mmproj_path);
// I k neuroni più attivi dello strato nell'ultimo token, i loro valori e la media di |a|. Ritorna quanti.
// Vale anche mentre il calcolo è delegato (fino a 32 neuroni).
int brain_layer_top(Brain *b, int layer, int k, int *idx, float *val, float *mean);
// OCR: il modello trascrive il testo di un'immagine (file jpg, png, bmp, gif...). Serve la visione (brain_vision_open).
// Ritorna i token scritti, -1 se la lettura è fallita, -2 se la visione non è disponibile, -3 se il file non è un'immagine.
int brain_ocr(Brain *b, const unsigned char *file, size_t len, char *out, size_t cap);