From ddf9212b81193d53c95b806edf86b125cb59e839 Mon Sep 17 00:00:00 2001 From: JustVugg Date: Wed, 15 Jul 2026 07:50:48 +0200 Subject: [PATCH] glm: PIN_GB=all clamps to the --ram budget instead of pinning every expert (fixes #229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PIN_GB=all passed gb=-1.0 to pin_load, which took npin=n (all experts) and ignored --ram entirely — the OOM-kill regression from #80. A 92 GB host with --ram 78 was killed mid-generation (anon-rss ~89 GB). Now gb<0 clamps npin to expert_avail() — how many experts fit the RAM budget, same accounting AUTOPIN uses. pin_load already adds the pinned bytes to resident_bytes, so the later cap_for_ram narrows the LRU accordingly with no double count. Co-Authored-By: Claude Opus 4.8 --- c/glm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/c/glm.c b/c/glm.c index 6309c94..c160008 100644 --- a/c/glm.c +++ b/c/glm.c @@ -4528,6 +4528,7 @@ typedef struct { int l,e; uint32_t c; } PinRec; static int pin_rec_cmp(const void *a,const void *b){ const PinRec *x=a,*y=b; return x->cc?1:x->c>y->c?-1:0; } +static double expert_avail(Model *m, double ram_gb, int ebits, int max_ctx); /* def. sotto */ static void pin_load(Model *m, const char *statspath, double gb){ FILE *f=fopen(statspath,"r"); if(!f){ perror(statspath); return; } Cfg *c=&m->c; int cap=(c->n_layers+1)*c->n_experts; @@ -4553,7 +4554,19 @@ static void pin_load(Model *m, const char *statspath, double gb){ free(seen); qsort(r,(size_t)n,sizeof(*r),pin_rec_cmp); int64_t eb=expert_bytes_probe(m,m->ebits); - int npin=gb<0?n:(int)(gb*1e9/eb); if(npin>n) npin=n; + /* PIN_GB=all (#80): NON "tutti" alla lettera. Pinnare l'intero set ignora il + * budget --ram e fa OOM-kill del kernel a meta' generazione (#229: host 92 GB + * ucciso con --ram 78, anon-rss 89 GB). Clampa a quanti expert entrano nel + * budget RAM, come AUTOPIN; il pin aggiorna resident_bytes, quindi cap_for_ram + * dopo restringe la LRU di conseguenza (nessun doppio conteggio). */ + int npin; + if(gb<0){ + double ram_env=getenv("RAM_GB")?atof(getenv("RAM_GB")):0.0; + int est_ctx=getenv("CTX")?atoi(getenv("CTX")):4096; /* stesso default del call site */ + double avail=expert_avail(m,ram_env,m->ebits,est_ctx); + npin=avail>0?(int)(avail/eb):0; + } else npin=(int)(gb*1e9/eb); + if(npin>n) npin=n; if(npin<1){ free(r); return; } int *cnt_l=calloc(c->n_layers+1,sizeof(int)); /* +1: riga MTP */ for(int a=0;a