ربط المحركات وتشغيل أول استنتاج محلي
في هذه المرحلة، أكملنا الجسر الكامل بين Rust ومحرك النصوص (llama.cpp) وشغّلنا أول inference محلي حقيقي على الجهاز بدون أي اتصال بالإنترنت.
ما تم إنجازه
البنية التحتية للـ FFI
- بناء
text_engine(llama.cpp) من المصدر بدون أدوات خارجية، وإنتاجlibllama.a+ مكتباتggml. - كتابة
build.rsلربط كل المكتبات الثابتة (libllama.a,libggml.a,libggml-base.a,libggml-cpu.a) مع OpenMP. - كتابة
pz_text_engine_wrapper.cpp— C++ wrapper يُخفي تعقيدات llama.cpp API ويعرض 3 دوال نظيفة:pz_llama_load(path)— تحميل نموذج GGUFpz_llama_complete(model, prompt, max_tokens)— توليد نصpz_llama_free(model)— تحرير الذاكرة
- تعريف FFI bindings في
src/ffi/llama.rsبصيغةunsafe extern "C"المتوافقة مع Rust 2024.
الخبراء (Experts)
OcrExpert— stub يقبلInput::Image(جاهز لربط vision_engine لاحقاً)LlamaExpert— يحمّل نموذج GGUF ويولّد نصاً عبرpz_llama_complete
النموذج
- Qwen2.5-0.5B-Instruct-Q4_K_M (~468MB) — نموذج متعدد اللغات يدعم العربية، يعمل محلياً بالكامل.
- مُخزَّن في
main/model/qwen2.5-0.5b-instruct-q4_k_m.gguf
الهيكل الحالي
main/
├── build.rs ← يبني الـ wrapper ويربط المكتبات
├── pz_text_engine_wrapper.cpp ← C++ wrapper لـ llama.cpp
├── model/
│ └── qwen2.5-0.5b-instruct-q4_k_m.gguf
└── src/
├── main.rs
├── ffi/llama.rs ← FFI bindings
├── experts/
│ ├── ocr_expert.rs
│ └── llama_expert.rs
├── manager/mod.rs
└── model/mod.rsنتيجة التشغيل النهائية ✅
السؤال: ما هي عاصمة المملكة العربية السعودية؟
الجواب:
النتيجة: عاصمة المملكة العربية السعودية هي الرياض. (الخبير: llama-text)🎯 رد نظيف، صحيح، ومختصر — بدون أي تكرار
كيف جاوب؟
المستخدم ──────────────────────────────────────────────────►
"ما هي عاصمة المملكة العربية السعودية؟"
│
▼
[Manager / Orchestrator - Rust]
يتعرف: Input::Text → يوجه لـ LlamaExpert
│
▼
[LlamaExpert - Rust]
يبني chat prompt بتنسيق Qwen2.5:
┌─────────────────────────────────────────┐
│ <|im_start|>system │
│ أنت مساعد ذكي... <|im_end|> │
│ <|im_start|>user │
│ ما هي عاصمة...؟ <|im_end|> │
│ <|im_start|>assistant │
└─────────────────────────────────────────┘
│
▼ unsafe FFI عبر pz_llama_complete()
[pz_text_engine_wrapper.cpp - C++]
- llama_tokenize() → يحوّل النص لأرقام
- llama_decode() → يحسب احتماليات الكلمات
- Sampler Chain:
penalty(1.15) → يمنع التكرار
temp(0.7) → يركّز الاختيار
dist(42) → يختار الـ token النهائي
- يولّد كلمة بعد كلمة حتى <|im_end|>
│
▼
"عاصمة المملكة العربية السعودية هي الرياض."لماذا اختفى التكرار؟
- Repetition Penalty 1.15: يُقلّل احتمالية إعادة الـ tokens المستخدمة مؤخراً
- Temperature 0.7: يجعل التوليد أكثر تركيزاً (أقل عشوائية)
- Chat Template: يُخبر النموذج بدوره ويضع حداً واضحاً للرد عند
<|im_end|>
الخطوة التالية
- تنفيذ
OcrExpertالفعلي عبر ربطvision_engine(ONNX Runtime)