نايا
جدول المحتويات
  1. 1دليل الفيديو
  2. 2Naia OS Live USB
  3. 3التثبيت والنشر
  4. 3.1تثبيت Naia OS (ISO)
  5. 3.2تثبيت التطبيق
  6. 4البدء
  7. 4.1Naia Model Pricing
  8. 4.2naia-omni-cascade
  9. 4.3demo
  10. 4.4naia-offline
  11. 4.5naia-model-dev
  12. 4.6naia-online
  13. 5الشاشة الرئيسية
  14. 6الدردشة
  15. 6.1منسق راديو شخصي ودليل المعرض
  16. 7تاريخ المحادثة
  17. 8تقدم العمل
  18. 9المهارات
  19. 10القنوات
  20. 11الوكلاء
  21. 12التشخيص
  22. 13مساحة العمل
  23. 14المتصفح
  24. 15إدارة اللوحات
  25. 16المحادثة الصوتية
  26. 17الإعدادات
  27. 18تفاصيل الأداة
  28. 19حساب Naia
  29. 20استكشاف الأخطاء وإصلاحها
  30. 21استخدام المصادر المفتوحة والمساهمة فيها

4.5. naia-model-dev

دليل المطورين لاستخدام نموذج Naia من الكود. بعد تشغيل النموذج عبر 4.4 تنزيل نموذج Naia، استخدم واجهة برمجة التطبيقات المتوافقة مع OpenAI المقدَّمة محلياً (دون بوابة، دون طابور) كما هي. مع أي SDK أو أداة من OpenAI، ما عليك سوى توجيه baseURL إلى هذا النموذج.

ليس مقتصراً على naia-os/الواجهة — أي كود يتحدث بلغة OpenAI Realtime/Chat/Audio/Embeddings يتصل كما هو، ويمكنك بناء وتشغيل تطبيقات جديدة فوق هذا النموذج.

1. الاتصال · المصادقة

  • قاعدة REST: http://<host>:8892/v1 (‏127.0.0.1 على نفس الجهاز)
  • فوري (WS): ws://<host>:8892/v1/realtime (يعمل ws://<host>:8892 المجرد أيضاً — يُطبَّق المسار /v1/realtime + النموذج الافتراضي تلقائياً)
  • الاتصال: على المحلي (127.0.0.1) / Tailscale، لا تُطلَب مصادقة — تتحقق الحاوية ذاتياً من ترخيصها. العملاء الذين يحتاجون إلى حقل مفتاح (مثل OpenAI SDK) يمكنهم تمرير أي قيمة (naia). عند الكشف عن بُعد، ضع Tailscale/VPN من §4.4 أمامه.

🔑 مفتاح واحد — مفتاح الاشتراك

  • مفتاح الاشتراك — مفتاح الاشتراك الذي تحصل عليه من البوابة. يُستخدَم فقط عند وقت تشغيل الحاوية (التفعيل) (-e NAIA_ACCOUNT_TOKEN=<subscription-key>). يتحقق من الاشتراك ويحصل على ترخيص محدود المدة (شهادة).
  • لا يوجد مفتاح اتصال منفصل. بمجرد التفعيل، تتحقق الحاوية ذاتياً محلياً بالشهادة، لذا يحتاج العملاء (‏naia-os، ‏OpenAI SDK) فقط إلى الاتصال عبر عنوان URL — ‏127.0.0.1 على نفس الجهاز، أو Tailscale/VPN (§4.4) من جهاز آخر. ولا يتصل بالبوابة عند كل اتصال.
  • إن api_key في الأمثلة أدناه هو قيمة بديلة (يتطلب OpenAI SDK هذا الحقل) — لا تتحقق الحاوية التي تعمل دون اتصال منه، لذا تعمل أي قيمة مثل "naia".

2. نقاط النهاية (متوافقة مع OpenAI)

نقطة النهايةالاستخدام
GET /healthالجاهزية {"ready":true,"services":{tts,stt,llm},"vad":true} (دون مصادقة)
GET /v1/modelsقائمة النماذج
WS /v1/realtimeجلسة صوتية فورية (VAD، مقاطعة، انفعال)
POST /v1/chat/completionsمحادثة (بث)
POST /v1/audio/speechتحويل النص إلى كلام (TTS)
POST /v1/audio/transcriptionsتحويل الكلام إلى نص (STT)
POST /v1/embeddingsتضمينات

محادثة (curl):

curl -s http://127.0.0.1:8892/v1/chat/completions \
  -H "Authorization: Bearer naia" -H "Content-Type: application/json" \
  -d '{"model":"naia-0.9-omni-24g","messages":[{"role":"user","content":"hi"}],"stream":false}'

OpenAI SDK (Python) — فقط بدّل baseURL:

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8892/v1", api_key="naia")
print(client.chat.completions.create(
    model="naia-0.9-omni-24g",
    messages=[{"role": "user", "content": "hi"}],
).choices[0].message.content)

النسخ النصي (STT):

curl -s http://127.0.0.1:8892/v1/audio/transcriptions \
  -H "Authorization: Bearer naia" \
  -F file=@sample.wav -F model=naia-0.9-omni-24g

3. الصوت الفوري — تدفق الاتصال (WS)

نفس التدفق الذي يستخدمه 4.3 العرض التوضيحي الحي. (يبدأ العمل دون اتصال فوراً، دون طابور/تخصيص بوابة.)

  1. الاتصال — افتح ws://<host>:8892.

  2. الإطار الأول (المصادقة · اللغة) — لا يمكن لـ WebSockets في المتصفح إرسال ترويسات، لذا أرسِل كأول رسالة:

    { "setup": { "apiKey": "naia", "locale": "en" } }
    
  3. عندما يرسل الخادم session.created، اضبط الجلسة باستخدام session.update:

    {
      "type": "session.update",
      "session": {
        "modalities": ["text", "audio"],
        "input_audio_format": "pcm16",
        "output_audio_format": "pcm16",
        "instructions": "<persona instructions>",
        "turn_detection": { "type": "server_vad" },
        "input_audio_transcription": { "language": "en" },
        "ref_audio_url": "<URL of a voice sample to mimic (optional)>"
      }
    }
    
  4. التبادل

    العميل → الخادم
    إدخال صوتي{"type":"input_audio_buffer.append","audio":"<base64 PCM16 24kHz>"} (يكتشف VAD في الخادم نهاية الكلام)
    إدخال نصيconversation.item.create ثم response.create
    المقاطعةresponse.cancel
    الخادم → العميل
    response.audio.deltaمقطع صوتي base64 PCM16 24kHz
    response.audio_transcript.delta / response.text.deltaنص الإجابة (بث)
    conversation.item.input_audio_transcription.completedنسخ كلامك
    emotion.updatedوسم الانفعال / التنغيم (§5)
    response.doneنهاية دور واحد

4. اللغات — 30 لغة (الافتراضي = تلقائي/عالمي)

يدعم النموذج 30 لغة (العربية، البورمية، الصينية، الدنماركية، الهولندية، الإنجليزية، الفنلندية، الفرنسية، الألمانية، اليونانية، العبرية، الهندية، الإندونيسية، الإيطالية، اليابانية، الخميرية، الكورية، اللاوية، الملايو، النرويجية، البولندية، البرتغالية، الروسية، الإسبانية، السواحيلية، السويدية، التغالوغية، التايلاندية، التركية، الفيتنامية).

  • الافتراضي (غير محدد) = عالمي/تلقائي — يكتشف اللغة التي تحدثت بها ويرد بتلك اللغة (لكل دور).
  • لتثبيت لغة محددة، أعطِ رمز ISO-639-1 (مثل ko/en/ja) في setup.locale أو في input_audio_transcription.language ضمن session.update.

5. تنسيق الإخراج (وسوم الانفعال · التنغيم)

تنسيق الإخراج مضبوط للمحادثة الصوتية — إذا عرفه العميل، فيمكنه التعبير بثراء أكبر.

  • وسوم التنغيم: يحتوي نص الإجابة على وسوم بأقواس مربعة بالإنجليزية بأحرف صغيرة مثل [laughing]، [sigh]، [breath]، [pause]، [hesitation] ممزوجة حيث تتحول الانفعالات (لتنغيم الكلام). النموذج مُوجَّه بألا يستخدم وسوماً كورية مثل [웃음]، أو إرشادات إخراجية بين أقواس مثل (smiling)، أو علامات نجمية مثل *smiles*. المفردات المعروفة: laughing/laugh/laughter/chuckle/giggle · sigh/exhale · breath/inhale · pause · hesitation · gasp/cough/sneeze/yawn/sniff/hum · cry/sob/moan/whisper/shout/cheer (تمرَّر الوسوم الأخرى كما هي).
  • لكل وسم، يرسل الخادم حدث emotion.updated بنسبة 1:1 (state == اسم الوسم، بأحرف صغيرة):
    { "type": "emotion.updated", "state": "laughing", "tag": "[laughing]", "known": true }
    
  • يحتفظ مسار TTS بالوسوم ويغذّيها في التركيب لتنغيم الكلام، بينما يرسل text.delta في المحادثة نصاً نظيفاً مع إزالة الوسوم. (لا رموز تعبيرية، ولا markdown، ولا سرد ذاتي بين أقواس في الإخراج.)
  • تعيين العميل (مرجع naia-os): عيّن emotion.updated.state (وسم التنغيم) إلى تعابير الصورة الرمزية — laughing/chuckle/giggle/cheer → happy، sigh/exhale/cry/sob → sad، gasp → surprised، shout → angry، hesitation → think. التنغيم غير الانفعالي مثل breath·pause لا يغيّر التعبير (احتفظ بالسابق — حتى لا يومض إلى المحايد مع كل نفَس).
  • يُوصى بمعالجة قوية: ليس إخراج LLM دقيقاً دائماً. فضّل emotion.updated، لكن إذا كان مفقوداً، اكتشف تلقائياً الوسوم في النسخ النصي نفسه (الأحرف الكبيرة [HAPPY] / وسوم التنغيم بأحرف صغيرة) أو الإرشادات الإخراجية المتسرّبة ((smiles)·*sigh*) واعكسها في التعبير؛ وإن لم تكن هناك إشارة، احتفظ بالتعبير الحالي (راجع naia-os shell/src/lib/vrm/expression.ts extractExpression).

6. تبديل نموذج المحادثة · رفع إصدار جديد (التشغيل)

هذا دليل تفصيلي للتبديل المباشر عبر سطر الأوامر. يمكن للمشتركين الأفراد استخدامه كما هو (دون مفتاح)، ويتضمن أيضاً خيار قفل لتشغيل المشاركة/الأكشاك. أما الملخص المبسّط فموجود في 4.4 دون اتصال.

6.1 تبديل نموذج المحادثة (اعتباراً من 0.91)

اترك الحاوية كما هي وبدّل فقط النموذج المسؤول عن المحادثة أثناء التشغيل. يبقى الصوت (التحدث · الاستماع) والعلامة المائية ومصادقة الاشتراك كما هي.

ثلاثة أمور تعرفها أولاً:

  1. النموذج الافتراضي هو نموذج لغوي مفتوح مدمج. يمكنك التبديل ثم العودة إلى الافتراضي في أي وقت.
  2. يجب أن يكون النموذج الجديد المراد رفعه بصيغة GGUF. وبما أن ميزة الصوت تستهلك نحو 10 جيجابايت من الذاكرة، يمكن لنموذج المحادثة أن يصل إلى نحو 14 جيجابايت. تُرفض النماذج الأكبر، وإذا فشل الرفع لأي سبب فإنه يعود تلقائياً إلى النموذج المستخدَم (لا تنقطع المحادثة).
  3. لا يحتاج المشتركون الأفراد إلى مفتاح منفصل. فمصادقة الاشتراك (الترخيص) على جهازك هي نفسها الصلاحية، لذا بدّل فقط بالأمر أدناه — تماماً كما لا يحتاج الصوت إلى مفتاح. (فقط على صناديق المشاركة/الأكشاك التي يستخدمها عدة أشخاص، يمكن للمشغّل وضع قفل بـ -e NAIA_ADMIN_KEY=كلمة_السر_المختارة عند التشغيل، وعندها تُرسَل -H "Authorization: Bearer كلمة_السر_المختارة" مع الطلب.)

تمرين — حدّد العنوان فقط:

BASE=http://127.0.0.1:8892     # من جهاز آخر، استخدم عنوان https في §4.4 (مثل ...:8443)

① انظر أي نموذج يعمل الآن وكم تبقّى من الذاكرة:

curl -s $BASE/admin/llm/status

② بدّل النموذج — استبدِل موضع النموذج داخل علامتي التنصيص فقط والصِقه. ضع عنوان بطاقة نموذج HuggingFace (https://huggingface.co/Qwen/Qwen2.5-7B-Instruct-GGUF) أو معرّفه (Qwen/Qwen2.5-7B-Instruct-GGUF) كما هو:

curl -s -X POST $BASE/admin/llm/swap \
  -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-7B-Instruct-GGUF","pull":true}'

تُضاف البادئة hf.co/ والجودة (quant) تلقائياً (الافتراضي Q4_K_M). إن أردت جودة محددة فاكتبها في النهاية مثل Qwen/Qwen2.5-7B-Instruct-GGUF:Q5_K_M. يستغرق تنزيل النموذج لأول مرة من عشرات الثواني إلى بضع دقائق.

②-دون اتصال — التبديل بملف GGUF لديك دون إنترنت. في حالات مثل المعارض والاستشارات حيث لا يوجد إنترنت، لا تنزّل من HuggingFace بل سجّل ملف GGUF تملكه بالفعل وبدّل إليه. (قاعدة التمييز: إذا كان الاسم يحتوي على شرطة مائلة مثل منظمة/مستودع فهو HuggingFace عبر الإنترنت، وإذا كان اسماً بسيطاً دون شرطة مائلة فهو نموذج محلي.)

انسخ والصق سطراً سطراً. ضع الاسم الذي تريده مكان mymodel، واسم الملف الفعلي مكان mymodel.gguf:

podman cp ./mymodel.gguf naia-omni:/app/models/mymodel.gguf
podman exec naia-omni sh -lc 'printf "FROM /app/models/mymodel.gguf\n" > /tmp/Modelfile && ollama create mymodel -f /tmp/Modelfile'
curl -s -X POST $BASE/admin/llm/swap -H "Content-Type: application/json" -d '{"model":"mymodel:latest","pull":false}'

⚠️ GGUF الذي حوّلته أو دمجته بنفسك قد يفتقر إلى قالب المحادثة فتصبح الإجابات مشوشة/مقطوعة. في تلك الحالة، أضِف في خطوة Modelfile الثانية قالب محادثة عائلة النموذج (TEMPLATE) ورموز التوقف (PARAMETER stop) ثم سجّله — التفاصيل للمطورين في [التنفيذ المرجعي §7]. (عادةً ما تتضمن GGUF الرسمية Instruct من HuggingFace ذلك، فتعمل كما هي.)

③ العودة إلى النموذج الافتراضي:

curl -s -X POST $BASE/admin/llm/restore

على صناديق المشاركة/الأكشاك (حين يضع المشغّل NAIA_ADMIN_KEY)، أضِف -H "Authorization: Bearer كلمة_السر_المختارة" إلى كل أمر أعلاه. أما المشتركون الأفراد فلا يحتاجون إليه.

حتى بعد التبديل، تتصل تطبيقات مثل naia-os بالعنوان نفسه كما هي (لا حاجة لإعادة الاتصال). وإن أردت أن يبدأ دائماً بذلك النموذج حتى بعد إعادة التشغيل أو التحديث، فحدّد النموذج الافتراضي عند تشغيل الحاوية بـ -e NAIA_LLM_MODEL=Qwen/Qwen2.5-7B-Instruct-GGUF.

6.2 التحديث إلى إصدار جديد

عند صدور إصدار جديد، بدّل الصورة (الإصدار) فقط واترك الاشتراك · الإعدادات كما هي. عند تشغيل الإصدار الجديد لأول مرة، تعيد الحاوية المصادقة تلقائياً عبر الإنترنت (نفس الاشتراك · الجهاز — لا حاجة لإدخال المفتاح يدوياً من جديد). لذا يجب أن تكون متصلاً بالإنترنت عند التحديث.

podman pull ghcr.io/nextain/naia-0.9-omni-24g:latest      # تنزيل أحدث إصدار
podman stop naia-omni && podman rm naia-omni      # تنظيف الحاوية فقط (انظر التنبيه أدناه)
# أعِد تنفيذ أمر التشغيل نفسه الذي استخدمته عند التثبيت الأول — فقط أربِط مجلد الترخيص نفسه وانتهى الأمر.

⚠️ عند التحديث، لا تضغط "تحرير الجهاز (release)". التحرير يُستخدَم فقط عند نقل الحاسوب المستخدَم إلى حاسوب آخر. إذا حرّرت أثناء محاولة التحديث، فستضطر إلى إعادة المصادقة من البداية. أما التحديث فيُبقي الاشتراك وتسجيل الجهاز ما دمت تترك مجلد الترخيص كما هو فقط.

المستخدِم الذي سبق أن صادق يكفيه تنزيل أحدث إصدار وإعادة تشغيله كما سبق لينتقل مباشرةً إلى الإصدار الجديد الذي يتيح تبديل النموذج (مع الحفاظ على المصادقة). ولتنزيل إصدار محدد بعينه، استخدم رقم الإصدار مثل :0.91 بدلاً من :latest.

7. انظر أيضاً

  • التنفيذ المرجعي / نموذج الكود (مفتوح المصدر): عميل الصوت في naia-os shell/src/lib/voice/ (Apache 2.0) — يحتوي على العميل الفعلي الذي يتحدث إلى واجهة برمجة التطبيقات هذه (naia-omni.ts) ومعالجة الانفعال/التنغيم (emotion-tags.ts؛ تعيين التعبير والاستخراج القوي في vrm/expression.ts). استخدمه كنقطة انطلاق لاختبار نماذج جديدة وبناء تطبيقات Tauri. جرّبه حياً في 4.3 العرض التوضيحي الحي.
  • التشكيلة والأسعار: 4.1 أسعار النماذج
  • السحابة (مخطط لها): 4.6 عبر الإنترنت