تحويل نماذج التعلم الآلي إلى API قابل للنشر باستخدام FastAPI

تحويل نماذج التعلم الآلي إلى API قابل للنشر باستخدام FastAPI

نشر نموذج تعلم آلي في بيئة الإنتاج لم يعد رفاهية، بل أصبح جزءًا أساسيًا من دورة حياة أي مشروع يعتمد على الذكاء الاصطناعي. بدلاً من تشغيل السكربت يدويًا وتمرير البيانات له، يمكنك تحويل النموذج إلى خدمة REST API يمكن استهلاكها من أي تطبيق ويب، موبايل، أو حتى سكربتات بايثون أخرى. في هذا المقال سنشرح خطوة بخطوة كيفية نشر نموذج ML FastAPI وتحويله إلى API قابل للاستدعاء بسهولة.

سنمر على مراحل: تجهيز النموذج، بناء مشروع FastAPI، إنشاء مسار للتنبؤ، تحسين الأداء، ثم نشر الخدمة بشكل آمن وفعّال على الخادم أو السحابة.

لماذا نستخدم FastAPI لنشر نماذج ML؟

إذا كنت قرأت سابقًا عن بناء RESTful APIs باستخدام FastAPI فستعرف أن FastAPI مصممة لتكون:

  • سريعة جدًا وتعتمد على ASGI وواجهة Starlette.
  • سهلة الاستخدام مع دعم ممتاز للتعليقات النوعية (type hints) في بايثون.
  • مناسبة للتكامل مع نماذج ML لأنها تدعم JSON، Pydantic، وعمليات التحقق من البيانات.
  • توفر وثائق تلقائية للـ API عبر Swagger UI و ReDoc.

هذه الخصائص تجعل FastAPI خيارًا مثاليًا عندما تريد تحويل نموذجك المدرب إلى خدمة ML API يمكن الوصول إليها عبر HTTP.

نظرة عامة على عملية نشر نموذج ML باستخدام FastAPI

لنشر نموذج تعلم آلي باستخدام FastAPI يمكنك تلخيص العملية في الخطوات التالية:

  1. تدريب النموذج وحفظه في ملف (Pickle، Joblib، أو SavedModel... إلخ).
  2. إنشاء مشروع FastAPI جديد وتنصيب الاعتمادات (Dependencies).
  3. تحميل النموذج داخل مشروع FastAPI في مرحلة بدء التطبيق.
  4. تعريف Schema لبيانات الإدخال (باستخدام Pydantic).
  5. إنشاء Endpoint للتنبؤ يقوم بـ:
    • استقبال المدخلات.
    • تمريرها للنموذج.
    • إرجاع نتيجة التنبؤ كـ JSON.
  6. اختبار الـ API محليًا.
  7. ضبط الأداء (Concurrency، Threading، أو Background Tasks).
  8. نشر الخدمة على خادم أو مزوّد سحابي (Docker، Uvicorn، Nginx... إلخ).

تجهيز نموذج التعلم الآلي للنشر

حفظ النموذج بعد التدريب

لنفرض أن لديك نموذجًا بسيطًا مدربًا باستخدام scikit-learn للتنبؤ بالسعر بناءً على بعض الخصائص. بعد التدريب، عادةً ما تحفظ النموذج بهذا الشكل:


import joblib

# model = ...  # بعد تدريب النموذج
joblib.dump(model, "model.joblib")

أهم النقاط هنا:

  • استخدام صيغة معروفة مثل joblib أو pickle لنماذج scikit-learn.
  • لمكتبات أخرى مثل TensorFlow أو PyTorch ستستخدم طريقة الحفظ الخاصة بها (مثل model.save() أو torch.save()).
  • تأكد من حفظ معالجة البيانات المسبقة (Scaler، Encoder...) مع النموذج أو في ملف منفصل حتى تستخدم نفس المنطق أثناء التنبؤ.

تنظيم ملفات المشروع

هيكلة بسيطة لمشروع نشر نموذج ML FastAPI يمكن أن تكون:


ml-fastapi-app/
├── app/
│   ├── main.py
│   ├── models/
│   │   └── model.joblib
│   ├── schemas.py
│   ├── predict.py
│   └── utils.py
├── requirements.txt
└── README.md

هذه الهيكلة تسهّل إدارة الكود، خاصةً عندما تكبر الخدمة ويزيد عدد النماذج أو نقاط النهاية.

إعداد FastAPI وتحميل النموذج

تثبيت الاعتمادات الأساسية

أولاً، قم بتثبيت الحزم المطلوبة:


pip install fastapi uvicorn joblib scikit-learn

إذا لم تكن معتادًا بعد على FastAPI، يمكنك العودة إلى مقال بناء أول موقع باستخدام FastAPI لتكوين فكرة عن أساسيات الإنشاء والتشغيل.

ملف main.py: إنشاء تطبيق 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)

هنا:

  • MODEL_PATH: يحدد مكان النموذج المحفوظ.
  • model = joblib.load(...): يتم التحميل لمرة واحدة فقط عند تشغيل الخادم.
  • المسار /predict يستقبل بيانات الطلب، يمررها لدالة make_prediction، ويرجع النتيجة.

تعريف Schemas لبيانات الإدخال والإخراج باستخدام Pydantic

نستخدم Pydantic (مدمج في FastAPI) لتحديد شكل بيانات الـ JSON المتوقعة والتحقق منها.

ملف schemas.py


# 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
    }
        

دالة التنبؤ وربطها بالنموذج

ملف predict.py

نفصل منطق التنبؤ في ملف مستقل لسهولة الاختبار والصيانة:


# 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])

يمكنك في هذه الدالة:

  • إضافة خطوات المعالجة المسبقة (Scaling, Encoding) التي كانت تُطبّق قبل التدريب.
  • التعامل مع الأخطاء المحتملة في شكل البيانات قبل تمريرها للنموذج.

تشغيل واختبار API محليًا

تشغيل الخادم باستخدام Uvicorn

من جذر المشروع:


uvicorn app.main:app --reload

سيتم تشغيل التطبيق بشكل افتراضي على:

  • http://127.0.0.1:8000
  • وثائق Swagger التلقائية: /docs
  • وثائق ReDoc: /redoc

اختبار Endpoint التنبؤ

يمكنك استخدام واجهة Swagger UI:

  1. افتح http://127.0.0.1:8000/docs.
  2. اختر POST /predict.
  3. اضغط على "Try it out".
  4. أدخل بيانات JSON المناسبة.
  5. سترى الاستجابة من النموذج في الأسفل.

أو يمكنك استخدام مكتبة 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())

التعامل مع الأداء في نشر نموذج ML FastAPI

الخطوة التالية بعد التأكد من أن API يعمل هي تحسين الأداء والاستجابة، خاصة إذا كان النموذج ثقيلًا (مثل نماذج الرؤية الحاسوبية أو النماذج العميقة).

اختيار عدد العمال (Workers) في Uvicorn/Gunicorn

في بيئة الإنتاج، غالبًا ستشغل FastAPI باستخدام Uvicorn مع Gunicorn:


gunicorn app.main:app -k uvicorn.workers.UvicornWorker --workers 4 --bind 0.0.0.0:8000
  • --workers 4: عدد العمليات بالتوازي، يعتمد على عدد أنوية المعالج.
  • يمكنك ضبط العدد بناءً على الاختبارات الحملية (Load Testing).

البرمجة غير المتزامنة (Async) لتحسين الأداء

FastAPI يدعم البرمجة غير المتزامنة باستخدام async def. إذا كان لديك عمليات إدخال/إخراج (I/O) مثل:

  • قراءة ملفات كبيرة.
  • الاتصال بخدمات أخرى (قواعد بيانات، APIs... إلخ).

فيمكنك استخدام البرمجة غير المتزامنة في بايثون: تحسين الأداء باستخدام async و await لتسريع الاستجابة. في حالة حسابات النموذج نفسها (CPU-bound) لن تستفيد كثيرًا من async لكنها مفيدة لباقي أجزاء الخدمة.

التحكم في تحميل النموذج واستخدام الذاكرة

  • تحميل واحد للنموذج: كما فعلنا في main.py، لتحاشي إعادة التحميل في كل طلب.
  • النماذج الثقيلة: يمكنك استخدام:
    • خدمة مستقلة لكل نموذج.
    • Load Balancer أمام عدة نسخ من الخدمة.
    • استخدام GPU إذا كان النموذج يعتمد على التعلم العميق.

اعتبارات الأمان عند نشر نموذج ML عبر API

فتح نموذجك للعالم يعني أن أي شخص يمكنه إرسال طلبات لخادمك. لذلك الأمان ضروري حتى لو كانت الخدمة "فقط للتنبؤ".

أساسيات تأمين RESTful APIs

تطرقنا إلى أفضل الممارسات في مقال أفضل ممارسات تصميم RESTful APIs آمن مع أمثلة، لكن نعيد هنا أهم النقاط المتعلّقة بنماذج ML:

  • المصادقة (Authentication):
    • استخدم مفاتيح API أو JWT Tokens إذا كانت الخدمة داخلية.
    • لا تترك Endpoint التنبؤ مفتوحًا بالكامل إذا كان النموذج ذا قيمة عالية.
  • تحديد معدل الطلبات (Rate Limiting):
    • لمنع إساءة الاستخدام (مثل إرسال آلاف الطلبات في الثانية) والتي قد تسقط الخادم.
    • يمكن تنفيذها عبر Nginx، Traefik، أو بوابة API.
  • التحقق من البيانات:
    • استخدم Pydantic للتأكد من أنواع القيم وحدودها.
    • تجنّب إدخال بيانات غير متوقعة قد تُسقط النموذج أو تسبّب استثناءات.
  • HTTPS:
    • تأكّد أن الوصول إلى API يتم عبر HTTPS، خاصة إذا كانت البيانات حساسة.

عزل النموذج عن بقية البنية التحتية

من الأفضل أن يكون خادم نموذج ML:

  • في شبكة خاصة (Private Network) إذا كان يُستهلك فقط من خدمات داخلية.
  • خلف بوابة (API Gateway) أو Reverse Proxy لإضافة طبقات أمان إضافية.

نشر نموذج ML FastAPI على الخادم أو السحابة

بعد أن يعمل كل شيء محليًا، حان وقت النشر. هناك عدة خيارات:

النشر باستخدام Docker

Docker يجعل عملية نقل الخدمة من البيئة المحلية إلى الخادم أكثر سهولة وتكرارًا.

ملف Dockerfile بسيط


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

استخدام Reverse Proxy مثل Nginx

غالبًا لن تعرض Uvicorn مباشرة للإنترنت، بل تضع أمامه Nginx لعدة أسباب:

  • إدارة SSL/HTTPS.
  • توزيع الحمل (Load Balancing) بين أكثر من نسخة من الخدمة.
  • تحديد معدل الطلبات (Rate Limiting) والـ Caching عند الحاجة.

خدمات سحابية

يمكن نشر خدمة FastAPI التي تحتوي على نموذجك على:

  • خادم VPS مثل DigitalOcean، Linode، أو غيرها.
  • خدمات حاويات مثل AWS ECS، Azure Container Apps، أو Google Cloud Run.
  • خدمات Functions (Serverless) إذا كان وقت الإقلاع للنموذج معقولاً.

نصائح عملية لتحسين تجربة نشر نموذج ML FastAPI

  • سجّل كل شيء (Logging):
    • سجّل الطلبات، الأخطاء، وأوقات الاستجابة لتحليل الأداء والمشاكل.
  • راقب النموذج في الإنتاج:
    • راقب تغيّر جودة التنبؤ (Data Drift, Concept Drift) مع مرور الوقت.
  • اعتمد إصدارات (Versioning) لنقاط النهاية:
    • مثلاً /v1/predict و /v2/predict عند تحديث النموذج، حتى لا تكسر التطبيقات القديمة.
  • التجربة في بيئة Staging:
    • قبل النشر النهائي على الإنتاج، اختبر الخدمة بنسخة بيانات قريبة من الواقع.

خلاصة: من نموذج مدرّب إلى خدمة ذكية قابلة للاستهلاك

تحويل نموذج التعلم الآلي إلى API قابل للنشر باستخدام FastAPI هو خطوة أساسية لنقل مشاريع الذكاء الاصطناعي من بيئة البحث والتجارب إلى بيئة الإنتاج الفعلية. من خلال:

  • حفظ النموذج ومعالجة البيانات المسبقة.
  • إعداد مشروع FastAPI منظم.
  • تعريف Schemas واضحة لبيانات الإدخال والإخراج.
  • إنشاء Endpoint للتنبؤ وربطه بالموديل.
  • تحسين الأداء باستخدام Uvicorn/Gunicorn والبرمجة غير المتزامنة عند الحاجة.
  • تطبيق أفضل ممارسات الأمان والنشر.

بهذه الخطوات، يصبح لديك نشر نموذج ML FastAPI جاهز للاستخدام من أي تطبيق أو خدمة أخرى، مع إمكانية التوسع والتطوير المستقبلي بسهولة. ومع تطور نماذج الذكاء الاصطناعي بشكل مستمر، امتلاك بنية قوية للنشر عبر API أصبح واحدًا من أهم المهارات لأي مطوّر أو مهندس بيانات اليوم.

حول المحتوى:

خطوات تحويل نموذج مدرّب إلى خدمة API قابلة للدعوة: تحميل النموذج، تصميم endpoint للتنبؤ، التعامل مع الأداء، وإرشادات نشر آمن وفعّال.

هل كان هذا مفيدًا لك؟

أضف تعليقك