تصویر از نویسنده
تصویر از نویسنده

تسریع در ارائه مدل یادگیری ماشین با FastAPI و ذخیره‌سازی Redis

راهنمای گام به گام برای افزایش سرعت استنتاج مدل با ذخیره‌سازی درخواست‌ها و تولید پاسخ‌های سریع.

Redis، یک فضای ذخیره‌سازی ساختار داده در حافظه و متن‌باز، یک انتخاب عالی برای ذخیره‌سازی در برنامه‌های یادگیری ماشین است. سرعت، دوام و پشتیبانی آن از ساختارهای مختلف داده، آن را برای مدیریت تقاضای بالا برای وظایف استنتاج در زمان واقعی ایده‌آل می‌کند.

در این آموزش، اهمیت ذخیره‌سازی Redis را در گردش کار یادگیری ماشین بررسی خواهیم کرد. ما نشان خواهیم داد که چگونه یک برنامه یادگیری ماشین قوی با استفاده از FastAPI و Redis بسازیم. این آموزش شامل نصب Redis بر روی ویندوز، اجرای آن به صورت محلی و ادغام آن در پروژه یادگیری ماشین خواهد بود. در نهایت، برنامه را با ارسال درخواست‌های تکراری و منحصربه‌فرد آزمایش خواهیم کرد تا تأیید کنیم که سیستم ذخیره‌سازی Redis به درستی کار می‌کند.

چرا از ذخیره‌سازی Redis در یادگیری ماشین استفاده کنیم؟

در چشم‌انداز دیجیتال پرشتاب امروزی، کاربران انتظار دارند نتایج فوری از برنامه‌های یادگیری ماشین دریافت کنند. به عنوان مثال، یک پلتفرم تجارت الکترونیکی را در نظر بگیرید که از یک مدل پیشنهادی برای پیشنهاد محصولات به کاربران استفاده می‌کند. با پیاده‌سازی Redis برای ذخیره‌سازی درخواست‌های مکرر، پلتفرم می‌تواند زمان پاسخگویی را به طور چشمگیری کاهش دهد.

هنگامی که یک کاربر درخواست توصیه‌های محصول می‌کند، سیستم ابتدا بررسی می‌کند که آیا درخواست ذخیره شده است یا خیر. اگر ذخیره شده باشد، پاسخ ذخیره شده در میکروثانیه برگردانده می‌شود و تجربه یکپارچه‌ای را ارائه می‌دهد. اگر نه، مدل درخواست را پردازش می‌کند، توصیه‌ها را ایجاد می‌کند و نتیجه را در Redis برای درخواست‌های آینده ذخیره می‌کند. این رویکرد نه تنها رضایت کاربر را افزایش می‌دهد، بلکه منابع سرور را نیز بهینه می‌کند و به مدل اجازه می‌دهد تا درخواست‌های بیشتری را به طور مؤثر مدیریت کند.

ساخت برنامه طبقه‌بندی ایمیل‌های فیشینگ با Redis

در این پروژه، ما یک برنامه طبقه‌بندی ایمیل‌های فیشینگ خواهیم ساخت. این فرآیند شامل بارگیری و پردازش مجموعه داده از Kaggle، آموزش یک مدل یادگیری ماشین بر روی داده‌های پردازش شده، ارزیابی عملکرد آن، ذخیره مدل آموزش داده شده و در نهایت ساخت یک برنامه FastAPI با ادغام Redis است.

۱. تنظیمات

  1. مجموعه داده تشخیص ایمیل فیشینگ را از Kaggle دانلود کرده و در دایرکتوری data/ قرار دهید.
  2. برای شروع، باید Redis را نصب کنید. دستور زیر را در ترمینال خود اجرا کنید تا کلاینت پایتون Redis را نصب کنید:
pip install redis
  1. اگر از ویندوز استفاده می‌کنید و Windows Subsystem for Linux (WSL) را نصب نکرده‌اید، راهنمای مایکروسافت را دنبال کنید تا WSL را فعال کرده و یک توزیع لینوکس (به عنوان مثال، اوبونتو) را از فروشگاه مایکروسافت نصب کنید.
  2. پس از تنظیم WSL، ترمینال WSL خود را باز کرده و دستورات زیر را برای نصب Redis اجرا کنید:
sudo apt update sudo apt install redis-server
  1. برای شروع سرور Redis، اجرا کنید:
sudo service redis-server start

باید یک پیام تأییدیه ببینید که نشان می‌دهد redis-server با موفقیت شروع شده است.

۲. آموزش مدل

اسکریپت آموزش، مجموعه داده را بارگیری می‌کند، داده‌ها را پردازش می‌کند، مدل را آموزش می‌دهد و آن را به صورت محلی ذخیره می‌کند.

import joblib import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.pipeline import Pipeline def main():  # Load dataset  df = pd.read_csv("data/Phishing_Email.csv")  # adjust the path as necessary  # Assume dataset has columns "text" and "label"  X = df["Email Text"].fillna("")  y = df["Email Type"]  # Split the dataset into training and testing sets  X_train, X_test, y_train, y_test = train_test_split(   X, y, test_size=0.2, random_state=42  )  # Create a pipeline with TF-IDF and Logistic Regression  pipeline = Pipeline(   [    ("tfidf", TfidfVectorizer(stop_words="english")),    ("clf", LogisticRegression(solver="liblinear")),   ]  )  # Train the model  pipeline.fit(X_train, y_train)  # Save the trained model to a file  joblib.dump(pipeline, "phishing_model.pkl")  print("Model trained and saved as phishing_model.pkl") if __name__ == "__main__":  main()
python train.py
Model trained and saved as phishing_model.pkl

۳. ارزیابی مدل

اسکریپت ارزیابی، مجموعه داده و فایل مدل ذخیره شده را برای انجام ارزیابی‌های مدل بارگیری می‌کند.

import pandas as pd from sklearn.metrics import classification_report, accuracy_score from sklearn.model_selection import train_test_split import joblib def main():  # Load dataset  df = pd.read_csv("data/Phishing_Email.csv")  # adjust the path as necessary  # Assume dataset has columns "text" and "label"  X = df["Email Text"].fillna("")  y = df["Email Type"]  # Split the dataset  X_train, X_test, y_train, y_test = train_test_split(   X, y, test_size=0.2, random_state=42  )  # Load the trained model  model = joblib.load("phishing_model.pkl")  # Make predictions on the test set  y_pred = model.predict(X_test)  # Evaluate the model  print("Accuracy: ", accuracy_score(y_test, y_pred))  print("Classification Report:")  print(classification_report(y_test, y_pred)) if __name__ == "__main__":  main()

نتایج تقریباً عالی هستند و امتیاز F1 نیز عالی است.

python validate.py
Accuracy:  0.9723860589812332 Classification Report:                 precision    recall  f1-score   support Phishing Email       0.96      0.97      0.96      1457     Safe Email       0.98      0.97      0.98      2273 accuracy                           0.97      3730    macro avg       0.97      0.97      0.97      3730 weighted avg       0.97      0.97      0.97      3730

۴. ارائه مدل با Redis

برای ارائه مدل، از FastAPI برای ایجاد یک REST API و ادغام Redis برای ذخیره‌سازی پیش‌بینی‌ها استفاده خواهیم کرد.

import asyncio import json import joblib from fastapi import FastAPI from pydantic import BaseModel import redis.asyncio as redis # Create an asynchronous Redis client (make sure Redis is running on localhost:6379) redis_client = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True) # Load the trained model (synchronously) model = joblib.load("phishing_model.pkl") app = FastAPI() # Define the request and response data models class PredictionRequest(BaseModel):  text: str class PredictionResponse(BaseModel):  prediction: str  probability: float @app.post("/predict", response_model=PredictionResponse) async def predict_email(data: PredictionRequest):  # Use the email text as a cache key  cache_key = f"prediction:{data.text}"  cached = await redis_client.get(cache_key)  if cached:   return json.loads(cached)  # Run model inference in a thread to avoid blocking the event loop  pred = await asyncio.to_thread(model.predict, [data.text])  prob = await asyncio.to_thread(lambda: model.predict_proba([data.text])[0].max())  result = {"prediction": str(pred[0]), "probability": float(prob)}  # Cache the result for 1 hour (3600 seconds)  await redis_client.setex(cache_key, 3600, json.dumps(result))  return result if __name__ == "__main__":  import uvicorn  uvicorn.run(app, host="0.0.0.0", port=8000)
python serve.py
INFO:     Started server process [17640] INFO:     Waiting for application startup. INFO:     Application startup complete. INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

با رفتن به URL http://localhost:8000/docs می‌توانید مستندات REST API را بررسی کنید

تسریع در ارائه مدل ML با FastAPI و ذخیره سازی Redis

کد منبع، فایل‌های پیکربندی، مدل‌ها و مجموعه داده برای این پروژه در مخزن GitHub kingabzpro/Redis-ml-project موجود است. در صورت بروز هرگونه مشکل در هنگام اجرای کد ارائه شده در بالا، می‌توانید از آن به عنوان مرجع استفاده کنید.

تسریع در ارائه مدل ML با FastAPI و ذخیره سازی Redis

نحوه کار ذخیره‌سازی Redis در برنامه‌های یادگیری ماشین

در اینجا یک توضیح گام به گام از نحوه عملکرد ذخیره‌سازی Redis در برنامه یادگیری ماشین ما به همراه یک نمودار برای نشان دادن این فرآیند آورده شده است:

  1. مشتری داده‌های ورودی را برای درخواست پیش‌بینی از مدل یادگیری ماشین ارسال می‌کند.
  2. یک شناسه منحصر به فرد بر اساس داده‌های ورودی تولید می‌شود تا بررسی شود که آیا پیش‌بینی قبلاً وجود دارد یا خیر.
  3. سیستم با استفاده از کلید تولید شده، کش Redis را برای جستجوی پیش‌بینی ذخیره شده قبلی جستجو می‌کند.
    1. اگر یک پیش‌بینی ذخیره شده پیدا شود، بازیابی شده و در یک پاسخ JSON برگردانده می‌شود.
    2. اگر هیچ پیش‌بینی ذخیره شده پیدا نشد، داده‌های ورودی به مدل یادگیری ماشین منتقل می‌شوند تا یک پیش‌بینی جدید تولید شود.
  4. پیش‌بینی تازه تولید شده در حافظه کش Redis برای استفاده در آینده ذخیره می‌شود.
  5. نتیجه نهایی در قالب JSON به مشتری بازگردانده می‌شود.

تست برنامه طبقه‌بندی ایمیل‌های فیشینگ

پس از ساخت برنامه طبقه‌بندی ایمیل‌های فیشینگ، زمان آزمایش عملکرد آن است. در این بخش، برنامه را با ارسال متون ایمیل متعدد با استفاده از دستور cURL و تجزیه و تحلیل پاسخ‌ها ارزیابی خواهیم کرد. علاوه بر این، پایگاه داده Redis را بررسی خواهیم کرد تا اطمینان حاصل کنیم که سیستم ذخیره‌سازی مطابق انتظار کار می‌کند.

تست API با استفاده از دستور CURL

برای تست API، پنج درخواست به نقطه پایانی /predict ارسال خواهیم کرد. در میان اینها، سه درخواست شامل متون ایمیل منحصر به فرد خواهد بود، در حالی که دو درخواست دیگر تکراری از ایمیل‌های ارسال شده قبلی خواهند بود. این به ما این امکان را می‌دهد تا هم دقت پیش‌بینی و هم مکانیسم ذخیره‌سازی را تأیید کنیم.

echo "\n===== Testing API Endpoint with 5 Requests =====\n" # First unique email echo "\n----- Request 1 (First unique email) -----" curl -X 'POST'  'http://localhost:8000/predict'  -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{  "text": "todays floor meeting you may get a few pointed questions about today article about lays potential severance of $ 80 mm" }' # Second unique email echo "\n\n----- Request 2 (Second unique email) -----" curl -X 'POST'  'http://localhost:8000/predict'  -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{  "text": "urgent action required: your account has been compromised, click here to reset your password immediately" }' # First duplicate (same as first email) echo "\n\n----- Request 3 (Duplicate of first email - should be cached) -----" curl -X 'POST'  'http://localhost:8000/predict'  -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{  "text": "todays floor meeting you may get a few pointed questions about today article about lays potential severance of $ 80 mm" }' # Third unique email echo "\n\n----- Request 4 (Third unique email) -----" curl -X 'POST'  'http://localhost:8000/predict'  -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{  "text": "congratulations you have won a free iphone, click here to claim your prize now before it expires" }' # Second duplicate (same as second email) echo "\n\n----- Request 5 (Duplicate of second email - should be cached) -----" curl -X 'POST'  'http://localhost:8000/predict'  -H 'accept: application/json'  -H 'Content-Type: application/json'  -d '{  "text": "urgent action required: your account has been compromised, click here to reset your password immediately" }' echo "\n\n===== Test Complete =====\n" echo "Now run 'python check_redis.py' to verify the Redis cache entries"

هنگامی که اسکریپت بالا را اجرا می‌کنید، API باید برای هر ایمیل پیش‌بینی‌ها را برگرداند. برای درخواست‌های تکراری، پاسخ باید از کش Redis بازیابی شود و از زمان پاسخگویی سریعتر اطمینان حاصل شود.

sh test.sh
\n===== Testing API Endpoint with 5 Requests =====\n \n----- Request 1 (First unique email) ----- {"prediction":"Safe Email","probability":0.7791625553383463}\n\n----- Request 2 (Second unique email) ----- {"prediction":"Phishing Email","probability":0.8895319031315131}\n\n----- Request 3 (Duplicate of first email - should be cached) ----- {"prediction":"Safe Email","probability":0.7791625553383463}\n\n----- Request 4 (Third unique email) ----- {"prediction":"Phishing Email","probability":0.9169092144856761}\n\n----- Request 5 (Duplicate of second email - should be cached) ----- {"prediction":"Phishing Email","probability":0.8895319031315131}\n\n===== Test Complete =====\n Now run 'python check_redis.py' to verify the Redis cache entries

تأیید حافظه پنهان Redis

برای تأیید اینکه سیستم ذخیره‌سازی به درستی کار می‌کند، از یک اسکریپت پایتون check_redis.py برای بازرسی پایگاه داده Redis استفاده می‌کنیم. این اسکریپت پیش‌بینی‌های ذخیره شده را بازیابی کرده و آنها را در قالب جدولی نمایش می‌دهد.

import redis import json from tabulate import tabulate def main():  # Connect to Redis (ensure Redis is running on localhost:6379)  redis_client = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)  # Retrieve all keys that start with "prediction:"  keys = redis_client.keys("prediction:*")  total_entries = len(keys)  print(f"Total number of cached prediction entries: {total_entries}\n")  table_data = []  # Process only the first 5 entries  for key in keys[:5]:   # Remove the 'prediction:' prefix to get the original email text   email_text = key.replace("prediction:", "", 1)   # Retrieve the cached value   value = redis_client.get(key)   try:    data = json.loads(value)   except json.JSONDecodeError:    data = {}   prediction = data.get("prediction", "N/A")   # Display only the first 7 words of the email text   words = email_text.split()   truncated_text = " ".join(words[:7]) + ("..." if len(words) > 7 else "")   table_data.append([truncated_text, prediction])  # Print table using tabulate (only two columns now)  headers = ["Email Text (First 7 Words)", "Prediction"]  print(tabulate(table_data, headers=headers, tablefmt="pretty")) if __name__ == "__main__":  main()

وقتی اسکریپت check_redis.py را اجرا می‌کنید، تعداد ورودی‌های کش و پیش‌بینی‌های ذخیره شده را در یک قالب جدولی نمایش می‌دهد.

python check_redis.py
Total number of cached prediction entries: 3 +--------------------------------------------------+----------------+ |            Email Text (First 7 Words)            |   Prediction   |                             +--------------------------------------------------+----------------+ |  congratulations you have won a free iphone,...  | Phishing Email | | urgent action required: your account has been... | Phishing Email | |      todays floor meeting you may get a...       |   Safe Email   | +--------------------------------------------------+----------------+

سخن پایانی

با آزمایش برنامه طبقه‌بندی ایمیل‌های فیشینگ با درخواست‌های متعدد، با موفقیت نشان دادیم که API می‌تواند ایمیل‌های فیشینگ را به طور دقیق شناسایی کند در حالی که به طور کارآمد درخواست‌های تکراری را با استفاده از Redis ذخیره می‌کند. این مکانیسم ذخیره‌سازی به طور قابل توجهی عملکرد را با کاهش محاسبات اضافی برای ورودی‌های تکراری بهبود می‌بخشد، که به ویژه در برنامه‌های دنیای واقعی که API ها حجم بالایی از ترافیک را مدیریت می‌کنند مفید است.

اگرچه این یک مدل نسبتاً ساده یادگیری ماشین بود، اما مزایای ذخیره‌سازی حتی در هنگام کار با مدل‌های بزرگتر و پیچیده‌تر، مانند تشخیص تصویر، بیشتر مشهود می‌شود. به عنوان مثال، اگر یک مدل طبقه‌بندی تصویر در مقیاس بزرگ را پیاده‌سازی می‌کردید، ذخیره‌سازی پیش‌بینی‌ها برای ورودی‌های مکرر پردازش شده می‌تواند منابع محاسباتی قابل توجهی را ذخیره کرده و به طور چشمگیری زمان پاسخگویی را بهبود بخشد.

عابد علی عوان (1abidaliawan@) یک متخصص داده‌شناس تایید شده است که عاشق ساخت مدل‌های یادگیری ماشین است. در حال حاضر، او بر ایجاد محتوا و نوشتن وبلاگ‌های فنی در مورد فناوری‌های یادگیری ماشین و علم داده تمرکز دارد. عابد دارای مدرک کارشناسی ارشد در مدیریت فناوری و مدرک لیسانس در مهندسی مخابرات است. چشم انداز او ساخت یک محصول هوش مصنوعی با استفاده از یک شبکه عصبی گراف برای دانش آموزانی است که با بیماری روانی دست و پنجه نرم می‌کنند.