طريقتان لإدراج LLM مجاني في نص Python
عندما يبحث الناس عن نماذج LLM مجانية لـ Python، فإنهم يقصدون عادةً أحد شيئين. الأول هو نموذج مفتوح الأوزان الذي تقوم بتنزيله وتشغيله بنفسك، باستخدام شيء مثل Ollama، أو llama.cpp، أو مكتبة Hugging Face transformers. والثاني هو نقطة نهاية مستضافة تكلف قليلاً جداً، أو تأتي مع رصيد تجريبي كافٍ، مما يجعلها تبدو مجانية لنموذج أولي. كلاهما مشروع، ويناسبان مهاماً مختلفة.
يعني التشغيل محلياً عدم وجود فاتورة لكل رمز وعدم خروج بيانات من جهازك. وهذا يعني أيضاً أنك تحتاج إلى ذاكرة RAM أو ذاكرة GPU كافية للنموذج الذي تختاره، وتنتظر التنزيلات، وأن النماذج الصغيرة التي تتسع للكمبيوتر المحمول تعطي نتائج أسوأ من النماذج الكبيرة. تزيل واجهة برمجة التطبيقات المستضافة سؤال الأجهزة، لكنك تدفع لكل رمز بمجرد انتهاء التجربة. يغطي هذا الصفحة كلا الأمرين بصراحة، ثم يظهر كود Python للخيار المستضاف على هذا الموقع، وهو متوافق مع OpenAI ويعمل مع الحزمة openai القياسية.
النماذج المحلية وواجهة برمجة التطبيقات المستضافة جنباً إلى جنب
| السؤال | تشغيله بنفسك | واجهة برمجة التطبيقات المستضافة مسبقة الدفع |
|---|---|---|
| التكلفة لكل رمز | لا، لكنك تدفع مقابل العتاد والطاقة | $0.15 لكل مليون رمز مدخل، $0.50 لكل مليون رمز مخرج |
| وقت الإعداد | ثبّت بيئة التشغيل، حمّل الأوزان، اضبط الإعدادات | ثبّت حزمة واحدة، الصق مفتاحاً |
| طول السياق | محدود بذاكرة جهازك | 100,000 رمز، الموجّه بالإضافة إلى الإكمال |
| الطلبات المتزامنة | ما تتحمّله أجهزتك | 8 طلبات متزامنة مع مفتاح كامل، و2 مع مفتاح تجريبي |
| الرفض | يعتمد على الأوزان التي تختارها | مضبط للإجابة بدون رفض المحتوى للاستخدام القانوني للبالغين |
| استخدام دون اتصال | نعم | لا |
إذا كانت لديك بطاقة رسومات (GPU) قوية وكان عملك خاصاً أو غير متصل، فإن التشغيل المحلي خيار جيد ويمكنك إيقاف القراءة هنا. إذا كنت تريد نموذجاً أكبر دون امتلاك العتاد، أو تريد أن يتصرف سكريبتك بنفس الطريقة على الحاسوب المحمول، الخادم، ومُشغّل CI، فإن المسار المستضاف أبسط. تستخدم العديد من المشاريع الاثنين: نموذجاً محلياً صغيراً أثناء التطوير، والمُستضاف في الإنتاج، ويتم التبديل بينهما بتغيير عنوان URL الأساسي.
أعد إعداد نقطة النهاية المستضافة في خمس دقائق
تحتاج إلى مفتاح أولاً. سجّل حسابك باستخدام Google أو عبر البريد الإلكتروني وكلمة المرور، ثم احصل على رصيد تجريقي بقيمة $0.50 بنقرة واحدة في صفحة مفتاح API. ساريان التجريبي لمدة 7 أيام، لكل شخص واحد، ولا يتطلب دفعاً. بعد ذلك، ثبّت الـ SDK واحتفظ بالمفتاح بعيداً عن كود المصدر.
pip install openai
export NOTRACK_API_KEY="sk-your-key-here"
يحتاج العميل إلى تغييرين مقارنة بإعداد OpenAI الافتراضي: عنوان URL الأساسي والمفتاح. معرف النموذج هو uncensored، ولا يُقدّم سوى نموذج واحد.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwvideogenerator.cc/v1",
api_key=os.environ["NOTRACK_API_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a concise writing assistant."},
{"role": "user", "content": "Give me three title ideas for a noir short story."},
],
temperature=0.8,
)
print(resp.choices[0].message.content)
print(resp.usage)
المصادقة هي رأس قياسي Authorization: Bearer، يضيفه لك الـ SDK تلقائياً. توجد طريقتان: POST /v1/chat/completions و GET /v1/models. يمكنك تأكيد الاتصال باستخدام client.models.list()، الذي يعيد معرف النموذج المتاح. القائمة الكاملة للمعاملات موجودة في صفحة الوثائق.
استجابات البث المتدفق
لأي شيء يشاهده شخص، فعّل البث المتدفق. اضبط stream=True وتصفّح القطع مع وصول أحداث الخادم المرسلة. يُبلغ عن الاستخدام في نهاية البث، لذا يمكنك لا تزال تسجيل عدد الرموز.
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a four-line poem about rain on a tin roof."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
usage = getattr(chunk, "usage", None)
if usage:
print("\n", usage)
تفاصيل واحدة قد تخدع المستخدمين: يحتفظ الطلب المتدفق بخانة التزامن حتى ينتهي البث. مع مفتاح تجريبي يتيح خانتين، يعني وجود بثّين مفتوحين أن الطلب الثالث سيحصل على خطأ 429 برمز concurrency. استهلك أو أغلق البث دائماً.
استدعاء الدوال ووضع JSON
تدعم نقطة النهاية tools، tool_choice، البث المتدفق لـ tool_calls والنتائج المرسلة كـ role: "tool". إليك رحلة كاملة مع دالة واحدة.
import json
tools = [{
"type": "function",
"function": {
"name": "word_count",
"description": "Count the words in a piece of text.",
"parameters": {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
},
},
}]
messages = [{"role": "user", "content": "How many words are in: the quick brown fox jumps"}]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = len(args["text"].split())
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result),
})
final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
print(final.choices[0].message.content)
قم دائماً بتحليل arguments بحذر؛ يعيدها النموذج كسلسلة JSON وقد ينتج أي نموذج سلسلة غير صالحة أحياناً. للإخراج الهيكلي بدون أدوات، استخدم وضع JSON.
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "Reply with a JSON object with keys title and tags (list of strings)."},
{"role": "user", "content": "Describe a lighthouse keeper's diary."},
],
response_format={"type": "json_object"},
temperature=0.2,
)
data = json.loads(resp.choices[0].message.content)
print(data["title"], data["tags"])
اذكر كلمة JSON واسم المفاتيح في الموجّه، واحتفظ بدرجة الحرارة منخفضة. لف json.loads داخل كتلة try لكود الإنتاج.
حدود المعدل، الأخطاء، وإعادة المحاولة
المفتاح الكامل يسمح بـ 8 طلبات متزامنة و300 طلب في الدقيقة. المفتاح التجريبي يسمح بـ 2 و60. تجاوز الحدود يعطيك خطأ HTTP 429 برمز rate_limited (عدد كبير جداً في الدقيقة) أو concurrency (عدد كبير جداً في آن واحد). عند الحمل الزائد المؤقت، تُعيد الـ API أيضاً خطأ 429 مع رأس Retry-After: 5. يعيد الـ SDK محاولة بعض الأخطاء تلقائياً؛ بالنسبة للسكريبت الذي يوزع الطلبات، فإن الغلاف الصريح البسيط أكثر وضوحاً.
import time
from concurrent.futures import ThreadPoolExecutor
from openai import RateLimitError
def ask(prompt, tries=4):
for attempt in range(tries):
try:
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": prompt}],
max_tokens=300,
)
return r.choices[0].message.content
except RateLimitError:
time.sleep(5 * (attempt + 1))
raise RuntimeError("still rate limited")
prompts = [f"Summarize idea number {i} in one sentence." for i in range(20)]
with ThreadPoolExecutor(max_workers=2) as pool: # 8 on a full key
results = list(pool.map(ask, prompts))
مطابقة max_workers مع حد الازدحام في مفتاحك يمنع معظم أخطاء 429 قبل وقوعها. يحمل كل استجابة أيضاً X-Request-Id، X-Balance-USD ورأسين لحدود المعدل، يمكنك قراءتهما عبر client.chat.completions.with_raw_response.create(...) عند الحاجة إليها للتصحيح أو الدعم.
كيفية الاختيار بين التشغيل المحلي والمستضاف
تخطَ الأيديولوجية وأجب عن أربع أسئلة حول مشروعك.
- هل يجب أن تبقى البيانات على جهازك؟ إذا قال العقد أو العادة نعم، شغّل محلياً. الموجّهات المستضافة لا تُستخدم للتدريب هنا، لكنها تسافر عبر الشبكة.
- كم الذاكرة المتاحة لديك؟ حجم النموذج يحدد الجودة. يحدّ الحاسوب المحمول بدون بطاقة رسومات مخصصة من استخدام النماذج الصغيرة، وستظهر الإجابات ذلك. يمنحك النموذج المستضاف نموذجاً كبيراً بنافذة سياق 100,000 رمز، وهو أمر صعب المطابقة في المنزل.
- كم طلباً سترسل؟ بضع مئات في الأسبوع أمر يسير على كلا الجانبين. مئات الآلاف في الشهر يحول فاتورة الاستضافة إلى رقم حقيقي، ويبدأ جهاز محلي في الظهور جذاباً إذا كان خاملًا بخلاف ذلك. احسب المجموع: 100,000 طلب من 1,000 رمز إدخال و500 رمز إخراج تكلف 100,000 × $0.0004 = $40.
- هل تحتاج إلى معالجة الرفض بطريقة معينة؟ العديد من النماذج مفتوحة الأوزان تأتي مع سلوك رفض مدمج، والنماذج الأخرى مضبوطة لإسقاطه. النموذج المستضاف هنا مضبوط للإجابة بدون رفض محتوى للاستخدام القانوني للبالغين، لذا لا تحتاج إلى البحث عن الأوزان الصحيحة.
إذا كانت إجاباتك تشير إلى الجانبين، ابدأ بالاستضافة للأسبوع الأول. التجربة لا تكلف شيئاً، وستتعلم ما يحتاجه الموجّه الخاص بك قبل شراء الأجهزة أو تنزيل ملف آخر بحجم عدة غيغابايت.
الأخطاء الشائعة في سكربتات Python
معظم المشاكل التي يواجهها الناس صغيرة وقابلة للإصلاح.
- عنوان URL الأساسي الخاطئ. يجب أن ينتهي بـ
/v1. اللاحقة المفقودة تعطي خطأ 404، وليس رسالة مفيدة. اطبعclient.base_urlإذا كنت في شك. - المفتاح في الكود. اقرأه من متغير بيئة، كما هو مذكور أعلاه، وأضف ملف
.envالخاص بك إلى.gitignore. - اسم النموذج الخاطئ. معرف النموذج الوحيد هو
uncensored. الأسماء من مزودين آخرين لن تعمل، لذا قم بتغييرها عند نقل الكود. - حلقات لا تنتهي. حلقة استدعاء الدوال التي لا تتوقف تُعدّ خطأً مكلفاً. اقطعها عند خمس جولات مثلاً.
- تجاهل ميزانية السياق. الموجّه والإكمال يشاركان 100,000 رمز. إذا ألصقت كل دور إلى الأبد، فستصل حتماً إلى الحد. قص أو لخص الرسائل القديمة.
- افتراض أن JSON صالح دائماً. حتى في وضع JSON، تحقق من المفاتيح التي تحتاجها قبل استخدامها.
عندما يبدو شيء ما خاطئاً من جانب الخادم، اقتبس قيمة X-Request-Id من الاستجابة عند الكتابة إلى support. هذا يسمح للمشغلين بإيجاد استدعائك بالضبط.
تكلفة خيار الاستضافة لأعمال Python
مكالمة نصية نموذجية مع 1,000 رمز إدخال و500 رمز إخراج تكلف $0.00015 بالإضافة إلى $0.00025، أي $0.0004. رصيد التجربة بقيمة $0.50 يغطي حوالي 1,250 منها. شحن بقيمة $20، وهو الحد الأدنى، يغطي 50,000. الرصيد لا ينتهي، الطلبات الفاشلة أو المرفوضة لا تُحسب، والموجّهات لا تُستخدم للتدريب. الشحنات تصل إلى $500 مع مكافأة من $50، والدفع بالعملات المشفرة، USDT على TRC20 أو USDC على Base. انظر صفحة التسعير للتفاصيل.
إنه نص فقط: لا صور، صوت، فيديو، تضمينات أو ضبط دقيق. والقاعدة الصارمة الوحيدة هي عدم وجود محتوى جنسي يتضمن القاصرين. لمشروع Python يحتاج إلى توليد النص مع رفض أقل، هذا هو النطاق بأكمله.
