diff --git a/dist/README.md b/dist/README.md index 9042b20..d1d7225 100644 --- a/dist/README.md +++ b/dist/README.md @@ -28,3 +28,6 @@ decode CPU. Modèle dense (Qwen3) plein NPU ; hybride (Qwen3.5 DDDA) GDN sur NPU Thinker Guard-4B → 4 bullets ; Speaker 9B = SYS_KAZEIA+bullets. Mono-moteur, `reset()` entre tours. Prompts: voir RAPPORT_KAZEIA §8. `--reasoning-budget 0` impératif (sinon ramble anglais) : EngineLlmEngine met thinking off. Mesuré: 9B>4B qualité, Speaker=9B. → MODELS.md (choix), PERF.md (chiffres), PITFALLS.md (params_fit, no tty, OOM 30B+), INTEGRATION.md (détail API). API: load/generate/reset/free. + +## VALIDÉ DEVICE 24/05 +test_native (=logique generate bridge) sur Pad3: load 4B HTP+decode CPU+detok = OUT propre, exit0. Pipeline prefill-NPU/decode-CPU prouve end-to-end. dist/jni/test_native.cpp = harness reproductible. Bridge so: 4 symboles JNI + deps ok. Reste app: gradle+jniLibs+template chat. diff --git a/dist/jni/test_engine.c b/dist/jni/test_engine.c new file mode 100644 index 0000000..401b693 --- /dev/null +++ b/dist/jni/test_engine.c @@ -0,0 +1,4 @@ +#include +#include +extern jlong Java_com_kazeia_llm_EngineJni_load(JNIEnv*,jobject,jstring,jint); +extern jstring Java_com_kazeia_llm_EngineJni_generate(JNIEnv*,jobject,jlong,jstring,jint); diff --git a/dist/jni/test_engine.cpp b/dist/jni/test_engine.cpp new file mode 100644 index 0000000..10eb318 --- /dev/null +++ b/dist/jni/test_engine.cpp @@ -0,0 +1,19 @@ +// Stub JNIEnv: valide libkazeia_engine.so generate() sur device, sans Java. +#include +#include +#include +struct Str { const char* s; }; +static const char* getUTF(void*, Str* j, void*){ return j->s; } +static void relUTF(void*, Str*, const char*){} +static Str* newUTF(void*, const char* s){ static Str r; r.s=s; return &r; } +// table indices: 169=NewStringUTF,167=GetStringUTFChars,168=Release (suffisant ici) +int main(int c, char** v){ + void* p[300]={0}; p[169]=(void*)newUTF; p[167]=(void*)getUTF; p[168]=(void*)relUTF; + void** env=p; void* h=dlopen("libkazeia_engine.so",RTLD_NOW); + if(!h){printf("dlopen fail: %s\n",dlerror());return 1;} + auto load=(long(*)(void**,void*,Str*,int))dlsym(h,"Java_com_kazeia_llm_EngineJni_load"); + auto gen=(Str*(*)(void**,void*,long,Str*,int))dlsym(h,"Java_com_kazeia_llm_EngineJni_generate"); + Str mp{v[1]}, pr{"Kazeia psy. Patient: je vais mal. Une phrase:"}; + long k=load(env,0,&mp,2048); printf("h=%ld\n",k); if(!k)return 2; + Str* r=gen(env,0,k,&pr,20); printf("OUT:[%s]\n",r->s); return 0; +} diff --git a/dist/jni/test_native.cpp b/dist/jni/test_native.cpp new file mode 100644 index 0000000..aaee1f2 --- /dev/null +++ b/dist/jni/test_native.cpp @@ -0,0 +1,20 @@ +// Valide la logique de generate() (prefill HTP + greedy CPU) sur device, sans JNI. +#include +#include +#include +#include "llama.h" +int main(int c, char** v){ + llama_backend_init(); + auto mp=llama_model_default_params(); mp.n_gpu_layers=99; + auto m=llama_model_load_from_file(v[1],mp); if(!m){printf("nomodel\n");return 1;} + auto cp=llama_context_default_params(); cp.n_ctx=2048; cp.n_threads=8; cp.n_batch=512; + auto ctx=llama_init_from_model(m,cp); auto vo=llama_model_get_vocab(m); + auto s=llama_sampler_init_greedy(); + const char* pr="Kazeia psy. Patient: je vais mal. Une phrase:"; + int n=-llama_tokenize(vo,pr,strlen(pr),0,0,true,true); std::vectort(n); + llama_tokenize(vo,pr,strlen(pr),t.data(),n,true,true); + auto b=llama_batch_get_one(t.data(),n); printf("OUT:"); + for(int i=0;i<20&&llama_decode(ctx,b)==0;i++){auto id=llama_sampler_sample(s,ctx,-1); + if(llama_vocab_is_eog(vo,id))break; char z[128]; int l=llama_token_to_piece(vo,id,z,128,0,true); + if(l>0)fwrite(z,1,l,stdout); b=llama_batch_get_one(&id,1);} printf("\n"); return 0; +} diff --git a/dist/test_engine b/dist/test_engine new file mode 100755 index 0000000..72b3530 Binary files /dev/null and b/dist/test_engine differ diff --git a/dist/test_native b/dist/test_native new file mode 100755 index 0000000..fdc3dca Binary files /dev/null and b/dist/test_native differ