حول المحتوى:
خطوات تحويل نموذج مدرّب إلى خدمة API قابلة للدعوة: تحميل النموذج، تصميم endpoint للتنبؤ، التعامل مع الأداء، وإرشادات نشر آمن وفعّال.
نشر نموذج تعلم آلي في بيئة الإنتاج لم يعد رفاهية، بل أصبح جزءًا أساسيًا من دورة حياة أي مشروع يعتمد على الذكاء الاصطناعي. بدلاً من تشغيل السكربت يدويًا وتمرير البيانات له، يمكنك تحويل النموذج إلى خدمة REST API يمكن استهلاكها من أي تطبيق ويب، موبايل، أو حتى سكربتات بايثون أخرى. في هذا المقال سنشرح خطوة بخطوة كيفية نشر نموذج ML FastAPI وتحويله إلى API قابل للاستدعاء بسهولة.
سنمر على مراحل: تجهيز النموذج، بناء مشروع FastAPI، إنشاء مسار للتنبؤ، تحسين الأداء، ثم نشر الخدمة بشكل آمن وفعّال على الخادم أو السحابة.
إذا كنت قرأت سابقًا عن بناء RESTful APIs باستخدام FastAPI فستعرف أن FastAPI مصممة لتكون:
هذه الخصائص تجعل FastAPI خيارًا مثاليًا عندما تريد تحويل نموذجك المدرب إلى خدمة ML API يمكن الوصول إليها عبر HTTP.
لنشر نموذج تعلم آلي باستخدام FastAPI يمكنك تلخيص العملية في الخطوات التالية:
لنفرض أن لديك نموذجًا بسيطًا مدربًا باستخدام scikit-learn للتنبؤ بالسعر بناءً على بعض الخصائص. بعد التدريب، عادةً ما تحفظ النموذج بهذا الشكل:
import joblib
# model = ... # بعد تدريب النموذج
joblib.dump(model, "model.joblib")
أهم النقاط هنا:
model.save() أو torch.save()).هيكلة بسيطة لمشروع نشر نموذج ML FastAPI يمكن أن تكون:
ml-fastapi-app/
├── app/
│ ├── main.py
│ ├── models/
│ │ └── model.joblib
│ ├── schemas.py
│ ├── predict.py
│ └── utils.py
├── requirements.txt
└── README.md
هذه الهيكلة تسهّل إدارة الكود، خاصةً عندما تكبر الخدمة ويزيد عدد النماذج أو نقاط النهاية.
أولاً، قم بتثبيت الحزم المطلوبة:
pip install fastapi uvicorn joblib scikit-learn
إذا لم تكن معتادًا بعد على FastAPI، يمكنك العودة إلى مقال بناء أول موقع باستخدام FastAPI لتكوين فكرة عن أساسيات الإنشاء والتشغيل.
سننشئ تطبيق FastAPI ونقوم بتحميل النموذج مرة واحدة عند بدء التطبيق لتفادي تكلفة التحميل في كل طلب:
# app/main.py
from fastapi import FastAPI
import joblib
from pathlib import Path
from .schemas import PredictionRequest, PredictionResponse
from .predict import make_prediction
app = FastAPI(title="ML Model API")
# تحميل النموذج عند بدء التشغيل
MODEL_PATH = Path(__file__).parent / "models" / "model.joblib"
model = joblib.load(MODEL_PATH)
@app.get("/")
def read_root():
return {"message": "ML API is running"}
@app.post("/predict", response_model=PredictionResponse)
def predict(request: PredictionRequest):
prediction = make_prediction(model, request)
return PredictionResponse(prediction=prediction)
هنا:
/predict يستقبل بيانات الطلب، يمررها لدالة make_prediction، ويرجع النتيجة.نستخدم Pydantic (مدمج في FastAPI) لتحديد شكل بيانات الـ JSON المتوقعة والتحقق منها.
# app/schemas.py
from pydantic import BaseModel
class PredictionRequest(BaseModel):
feature1: float
feature2: float
feature3: float
class PredictionResponse(BaseModel):
prediction: float
بهذا الشكل:
/predict يجب أن يحتوي JSON مثل:
{
"feature1": 1.0,
"feature2": 2.5,
"feature3": 0.7
}
{
"prediction": 123.45
}
نفصل منطق التنبؤ في ملف مستقل لسهولة الاختبار والصيانة:
# app/predict.py
import numpy as np
from .schemas import PredictionRequest
def make_prediction(model, request: PredictionRequest) -> float:
# تحويل المدخلات إلى مصفوفة بالشكل المناسب للنموذج
data = np.array([[request.feature1, request.feature2, request.feature3]])
pred = model.predict(data)
# نفترض أن النموذج يرجع قيمة عددية واحدة
return float(pred[0])
يمكنك في هذه الدالة:
من جذر المشروع:
uvicorn app.main:app --reload
سيتم تشغيل التطبيق بشكل افتراضي على:
http://127.0.0.1:8000/docs/redocيمكنك استخدام واجهة Swagger UI:
http://127.0.0.1:8000/docs.POST /predict.أو يمكنك استخدام مكتبة Requests من بايثون، كما شرحنا بالتفصيل في دليل استخدام مكتبة Requests:
import requests
url = "http://127.0.0.1:8000/predict"
payload = {
"feature1": 1.0,
"feature2": 2.5,
"feature3": 0.7
}
response = requests.post(url, json=payload)
print(response.json())
الخطوة التالية بعد التأكد من أن API يعمل هي تحسين الأداء والاستجابة، خاصة إذا كان النموذج ثقيلًا (مثل نماذج الرؤية الحاسوبية أو النماذج العميقة).
في بيئة الإنتاج، غالبًا ستشغل FastAPI باستخدام Uvicorn مع Gunicorn:
gunicorn app.main:app -k uvicorn.workers.UvicornWorker --workers 4 --bind 0.0.0.0:8000
FastAPI يدعم البرمجة غير المتزامنة باستخدام async def. إذا كان لديك عمليات إدخال/إخراج (I/O) مثل:
فيمكنك استخدام البرمجة غير المتزامنة في بايثون: تحسين الأداء باستخدام async و await لتسريع الاستجابة. في حالة حسابات النموذج نفسها (CPU-bound) لن تستفيد كثيرًا من async لكنها مفيدة لباقي أجزاء الخدمة.
main.py، لتحاشي إعادة التحميل في كل طلب.فتح نموذجك للعالم يعني أن أي شخص يمكنه إرسال طلبات لخادمك. لذلك الأمان ضروري حتى لو كانت الخدمة "فقط للتنبؤ".
تطرقنا إلى أفضل الممارسات في مقال أفضل ممارسات تصميم RESTful APIs آمن مع أمثلة، لكن نعيد هنا أهم النقاط المتعلّقة بنماذج ML:
من الأفضل أن يكون خادم نموذج ML:
بعد أن يعمل كل شيء محليًا، حان وقت النشر. هناك عدة خيارات:
Docker يجعل عملية نقل الخدمة من البيئة المحلية إلى الخادم أكثر سهولة وتكرارًا.
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app ./app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
ثم:
docker build -t ml-fastapi-app .
docker run -d -p 8000:8000 ml-fastapi-app
غالبًا لن تعرض Uvicorn مباشرة للإنترنت، بل تضع أمامه Nginx لعدة أسباب:
يمكن نشر خدمة FastAPI التي تحتوي على نموذجك على:
/v1/predict و /v2/predict عند تحديث النموذج، حتى لا تكسر التطبيقات القديمة.تحويل نموذج التعلم الآلي إلى API قابل للنشر باستخدام FastAPI هو خطوة أساسية لنقل مشاريع الذكاء الاصطناعي من بيئة البحث والتجارب إلى بيئة الإنتاج الفعلية. من خلال:
بهذه الخطوات، يصبح لديك نشر نموذج ML FastAPI جاهز للاستخدام من أي تطبيق أو خدمة أخرى، مع إمكانية التوسع والتطوير المستقبلي بسهولة. ومع تطور نماذج الذكاء الاصطناعي بشكل مستمر، امتلاك بنية قوية للنشر عبر API أصبح واحدًا من أهم المهارات لأي مطوّر أو مهندس بيانات اليوم.
خطوات تحويل نموذج مدرّب إلى خدمة API قابلة للدعوة: تحميل النموذج، تصميم endpoint للتنبؤ، التعامل مع الأداء، وإرشادات نشر آمن وفعّال.
مساحة اعلانية