🦀

ربط المحركات وأول استنتاج محلي

SYS.TIME12 أغسطس 2026 - 14:00 PM (GMT+3)
CATEGORYالتأسيس

ربط المحركات وتشغيل أول استنتاج محلي ​

في هذه المرحلة، أكملنا الجسر الكامل بين 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) — تحميل نموذج GGUF
    • pz_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)