neuronal-gpu / src /brain_worker.c
amogaddy's picture
Neuronal: modello su ZeroGPU
17b2436 verified
Raw History Blame Contribute Delete
3.02 kB
// neuronal-brain: il solo modello, per una GPU presa in prestito (ZeroGPU di Hugging Face).
// Carica il cervello, riceve dal motore lo stato dei neuroni e le richieste di lettura e generazione,
// rimanda indietro le parole e le attivazioni. Pagina, strumenti, voce e ricordi restano nel motore.
//
// Parla sullo standard input/output a blocchi [u32 lunghezza][dati]: un ponte (ponte.py) li porta
// al motore su un WebSocket. Tutto quello che il programma stampa va sullo standard error.
//
// Uso: neuronal-brain MODELLO CARTELLA_BACKEND [PROIETTORE_IMMAGINI] [CONTESTO]
#include "brain.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#include <windows.h>
#else
#include <poll.h>
#include <unistd.h>
#endif
typedef struct { int in, out; } Pipe;
static bool read_all(int fd, void *buf, size_t n) {
char *p = buf;
while (n) {
int r = (int)read(fd, p, (unsigned)(n < (1u << 20) ? n : (1u << 20)));
if (r <= 0) return false;
p += r;
n -= (size_t)r;
}
return true;
}
static bool write_all(int fd, const void *buf, size_t n) {
const char *p = buf;
while (n) {
int r = (int)write(fd, p, (unsigned)(n < (1u << 20) ? n : (1u << 20)));
if (r <= 0) return false;
p += r;
n -= (size_t)r;
}
return true;
}
static bool readable(int fd) {
#ifdef _WIN32
DWORD avail = 0;
return PeekNamedPipe((HANDLE)_get_osfhandle(fd), NULL, 0, NULL, &avail, NULL) && avail > 0;
#else
struct pollfd p = {fd, POLLIN, 0};
return poll(&p, 1, 0) > 0;
#endif
}
static bool pipe_send(void *ud, const void *data, size_t len) {
Pipe *p = ud;
uint32_t n = (uint32_t)len;
return write_all(p->out, &n, 4) && write_all(p->out, data, len);
}
static void *pipe_recv(void *ud, size_t *len, int timeout_ms) {
Pipe *p = ud;
if (timeout_ms == 0 && !readable(p->in)) return NULL;
uint32_t n = 0;
if (!read_all(p->in, &n, 4) || n > (64u << 20)) return NULL;
uint8_t *buf = malloc(n ? n : 1);
if (!read_all(p->in, buf, n)) { free(buf); return NULL; }
*len = n;
return buf;
}
int main(int argc, char **argv) {
if (argc < 3) {
fprintf(stderr, "uso: %s MODELLO CARTELLA_BACKEND [PROIETTORE_IMMAGINI] [CONTESTO]\n", argv[0]);
return 1;
}
// lo standard output porta i blocchi: quello che le librerie stampano finisce sullo standard error
fflush(stdout);
Pipe io = {0, dup(1)};
dup2(2, 1);
#ifdef _WIN32
_setmode(io.in, _O_BINARY);
_setmode(io.out, _O_BINARY);
#endif
const char *mmproj = argc > 3 && argv[3][0] ? argv[3] : NULL;
int n_ctx = argc > 4 ? atoi(argv[4]) : 32768;
Brain *b = brain_open(argv[1], n_ctx, argv[2], 999);
if (!b) { fprintf(stderr, "neuronal-brain: impossibile caricare il modello sulla GPU\n"); return 2; }
BrainLink l = {&io, NULL, NULL, pipe_send, pipe_recv, NULL};
brain_serve(b, &l, mmproj);
brain_close(b);
return 0;
}