نویسندگان : محیا مهدیان و محمد حسن ستاریان
پس از اینکه یک مدل را آموزش دادیم، میخواهیم یک سرور سبک و کوچک داشته باشیم تا بتوانیم با فرستادن عکس نتیجه پیشبینی (Predict) مدل را دریافت کنیم، درواقع کاری میکنیم که امکان پیشبینی از هرجایی از طریق اینترنت فراهم باشد. اینکار کمک میکند بتوانیم سرویسها و حتی اپلیکیشنهایی برای استفاده عملی از مدل خود داشته باشیم.
برای اینکار چندین راه وجود دارد؛ در این پست ما روشهای اجرای لوکال، دپلوی با Heroku و اجرا از سرور ریموت را بررسی میکنیم.
اجرای لوکال
اگر در فکرید که اجرای لوکال به دسترسی از طریق اینترنت چه ربطی دارد، اجازه بدید ابزار مورد نیاز این روش را معرفی کنیم:
ابزارها
ngrok – ابزاری رایگان برای ایجاد تونل از اینترنت به یک پورت در سیستم لوکال است. ngrok یک آدرس قابل دسترس از اینترنت به پورت مشخص شده میدهد تا بتوان ترافیک پورت را از خارج سیستم از طریق اینترنت دریافت کرد.
Flask – فلسک یک میکروفریمورک سبک برای راهاندازی سریع و راحت وبسرور است. آموزش مقدماتی فلسک را بخوانید.
قبل از شروع، طبق این مراحل ngrok را نصب کرده و آنرا به PATH سیستم خود اضافه کنید.
طبق آموزش مقدماتی فلسک، کدی مانند نمونه کد زیر برای سروری که قادر به گرفتن عکس (upload)، لود مدل آموزش دادهشده (Load model)، پیشبینی عکس (Predict) و برگرداندن خروجی است، بنویسید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import keras from flask import Flask, flash, redirect, request, send_from_directory, url_for app = flask.Flask(__name__) def load_model() ... loads model def prepare_image(): ... proccess image for prediction return image @app.route("/predict", methods=["POST"]) def predict(): if flask.request.method == "POST": if flask.request.files.get("image"): ... gets image and call prepare_image() and do predict return flask.jsonify(data) @app.route("/predictLastImageAgain") def predictAgain(): predict() @app.route("/lastUploadedImage") def lastUploadedImage(): return send_from_directory('uploads/', 'imageToPredict.jpg') if __name__ == "__main__": load_model() app.run() |
سپس، سرور فلسک را با وارد کردن دستور زیر در ترمینال اجرا کنید:
1 |
python server.py |
پس از اجرا، سرور در آدرس http://localhost:5000 در دسترس میشود.
حال با استفاده از ngrok به این سرور یک آدرس قابل دسترس در اینترنت اختصاص میدهیم؛ برای اینکار یک ترمینال جدید باز کرده و دستور زیر را وارد میکنیم:
1 |
ngrok http 5000 |
در این دستور با فراخوانی ngrok گفته ایم به برنامه درحال اجرا در پورت ۵۰۰۰ میخواهیم دسترسی از طریق پروتکل http بدهیم. پس از اجرای دستور بالا مطابق شکل زیر آدرسی که میتوان برای دسترسی به سرور استفاده کرد به همراه آدرس مدیریت سرویس ngrok به نمایش درمیآید:
پس از آن میتوانید از طریق این آدرس و endpoint های تعریف شده از مدل خود استفاده کنید.
دپلوی با Heroku
شاید سختترین روش بین دو روش دیگر این روش و استفاده از Heroku است و مفاهیمی که این روش به عنوان پیشنیاز لازم دارد تا آشنا باشید کم نیستند. اما شاید از روشهای دیگر سختتر باشد اما میتواند جذابتر و حتی پرکاربرد تر باشد. همچنین لازم به ذکر است این سرویس فعلا برای استفاده مسدود بوده و نیاز به اتصال غیر مستقیم است و در استفاده رایگان حجم پروژه نباید از ۵۰۰ مگابایت بیشتر باشد.
ابزارها
Heroku – سرویس (PaaS (Platform as a service ای و درواقع بستری به عنوان سرویس ابری است که از زبانهای برنامه نویسی زیادی پشتیبانی میکند که برنامه نویس را از کارهای DevOps لازم برای راهاندازی یک سرور بینیاز میکند.
Flask – فلسک یک میکروفریمورک سبک برای راهاندازی سریع و راحت وبسرور است. آموزش مقدماتی فلسک را بخوانید.
Github – گیتهاب سرویس میزبانی و کنترل نسخه تحت وب قدرت گرفته از گیت (git) است.
GitLFS – سیستم مدیریت فایلهای حجیم گیت.
GitLFS سرویس ارائه شده توسط GitHub برای کنترل نسخه فایلهای حجیم (حجیم تر از ۵۰ مگابایت) است و چون ما در پروژه خود فایلهای نظیر فایل مدل آموزش داده شده و شاید فایلهای دیگر داشته باشیم به این برنامه احتیاج داریم.
در ادامه مطابق آموزش شروع استفاده از Heroku با زبان پایتون، دلپوی برنامه خود (سرور پیشبینی) را، با استفاده از خط فرمان -و با شروع از سیستم خود- بررسی میکنیم؛ اما، این مراحل از طریق داشبورد Heroku که پس از ساخت اکانت در هروکو به آن دسترسی دارید نیز قابل انجام است. خوب است برای برنامه خود یک محیط مجازی پایتون ایجاد کرده، پیشنیازهای آن را نصب کرده از اجرای لوکال آن مطمئن شده و سپس اقدام به دپلوی آن کنید.برای آشنایی بیشتر آموزش ایجاد محیط مجازی پایتون و آموزش ایجاد سرور فلسک را بخوانید.
ورود
قبل از هر چیز یک اکانت رایگان در Heroku بسازید. اگر پایتون را به صورت لوکال نصب ندارید از اینجا دریافت کنید. در ادامه رابط خط فرمان Heroku را نصب کنید.
پس از نصب موارد فوق، ترمیتال را باز کرده و با استفاده از دستور زیر در Heroku لاگین میکنیم:
1 2 3 4 5 6 7 |
heroku login # Output Enter your Heroku credentials. Email: python@example.com Password: ... |
پس از اجرای دستور، ایمیل و رمزعبور خود را وارد کرده تا وارد شوید.
آمادهسازی
اگر برنامه شما توسط git مدیریت نمیشود با استفاده از دستور git init آنرا فعال کنید. همچنین فایلهای حجیم خود را مشخص کنید تا GitLFS آنها را مدیریت کند:
1 |
git lfs track [mdoel.h5] # This will create a .gitattributes file |
در این مثال فایل model.h5 را که فایل مدل ذخیره شده است و حجم بیشتر از ۵۰ مگابایت دارد را با استفاده از GitLFS مدیریت میکنیم.
سپس، با استفاده از دستور زیر یک اپلیکیشن در Heroku درست میکنید که آماده دریافت سورس و اجرای آن است:
1 2 3 4 5 6 |
heroku create # output Creating lit-bastion-5032 in organization heroku... done, stack is cedar-14 http://lit-bastion-5032.herokuapp.com/ | https://git.heroku.com/lit-bastion-5032.git Git remote heroku added |
با اجرای این دستور یک git remote به نام heroku مرتبط با ریپوزیتوری گیت لوکال شما اضافه خواهد شد. همچنین، یک نام تصادفی (در این مثال lit-bastion-5032 ) به این برنامه تخصیص داده میشود. همچنین میتوان با وارد کردن یک نام دلخواه نام مورد نظر خود را به اپلیکیشن اختصاص داد.
هروکو با استفاده از چند فایل تنظیم، تصمیم میگیرد برنامه را به چه صورت و با استفاده از چه سرویسی اجرا کند. برای آنکه مشخص کنیم برنامه چگونه باید اجرا شود به سه کانفیگ فایل runtime.txt و requirements.txt به همراه فایل Procfile نیاز داریم.
runtime.txt
این فایل شامل توضیحاتی در مورد محیط اجرای برنامه و درواقع زبان مورد استفاده است.
ما این فایل را با محتوی زیر ایجاد میکنیم:
1 |
python-3.6.4 |
requirements.txt
این فایل، پیشنیازهای اجرای برنامه را مشخص میکند.
ما این فایل را با خروجی دستور pip freeze که پکیجهای نصب شده برای پروژه را چاپ میکند به صورت زیر ایجاد میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 |
gunicorn decorator==4.3.0 Flask==0.12.1 Flask-Uploads==0.2.1 h5py==2.7.1 html5lib==0.9999999 Keras==2.1.6 numpy==1.14.2 scikit-learn==0.19.1 scipy==1.1.0 tensorflow==1.7.0 Werkzeug==0.12.1 |
Procfile
این فایل، شامل توضیحات نحوه اجرای برنامه است.
ما ابن فایل را با دستور زیر ایجاد خواهیم کرد:
1 |
web: gunicorn app:server |
این دستور بیان میکند که برنامه ما یک برنامه از نوع web بوده و لازم است با استفاده از برنامه سرور gunicorn اجرا شود و فایل اجرایی اپلیکیشنی به نام server است.
دلیل استفاده از سرور gunicorn بجای سرور پیشفرض پایتون این است که هروکو از این سرور برای اجرا، بخصوص برای اجرای فلسک استفاده میکند.
نکته مهم استفاده از gunicorn این است که این برنامه ابتدا یک سرور اجرا کرده سپس برنامه ما را در آن import میکند. از آنجایی که برنامه ما خود سرو خواهد شد نیازی به دستور ()app.run نخواهد بود و اگر در کد خود از این دستور استفاده کرده ایم باید آن را مانند مثال زیر در شرط بررسی import شدن یا نشدن ماژول قرار دهیم:
1 2 |
if __name__ == '__main__': app.run() |
با اعمال تغییرات فوق و اضافه کردن کانیفگ فایلها، این تغییرات را با استفاده از گیت کنترل میکنیم:
1 2 3 |
git add -A git commit -m "Add required config files to deploy using heroku" |
قبل از ادامه دپلوی با استفاده از دستور heroku local web میتوانیم سرور خود را به صورت لوکال تست کنیم، اما از آنجایی که برنامه gunicorn در ویندوز قابل اجرا نیست اگر از ویندوز استفاده میکنید این امکان وجود نخواهد داشت.
حال اگر برنامه ما نیاز به تغییر نداشته و آماده push کردن هستیم، با دستور زیر برنامه را در ریپوزیتوری ریموتی که هروکو در اختیارمان گذاشته بود push میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
git push heroku master # output Counting objects: 232, done. Delta compression using up to 4 threads. Compressing objects: 100% (217/217), done. Writing objects: 100% (232/232), 29.64 KiB | 0 bytes/s, done. Total 232 (delta 118), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Python app detected remote: -----> Installing python-3.6.0 remote: -----> Installing requirements with latest pipenv... remote: Installing dependencies from Pipfile.lock... remote: $ python manage.py collectstatic --noinput remote: 58 static files copied to '/app/gettingstarted/staticfiles', 58 post-processed. remote: remote: -----> Discovering process types remote: Procfile declares types -> web remote: remote: -----> Compressing... remote: Done: 39.3M remote: -----> Launching... remote: Released v4 remote: http://lit-bastion-5032.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To git@heroku.com:lit-bastion-5032.git * [new branch] master -> master |
اگر همه چیز موفقیت آمیز باشد، برنامه ما دپلوی شده و آماده استفاده است. قبل از آن با استفاده از دستور زیر مطمئن میشویم که حداقل یک نمونه از این برنامه درحال اجرا باشد:
1 |
heroku ps:scale web=1 |
با استفاده از دستور زیر میتوانیم آدرس اختصاص داده شده به برنامه را در مرورگر باز کنیم:
1 |
heroku open |
برنامه آماده استفاده است!
روش بهتر استفاده از هروکو این است که ابتدا فایلهای پروژه را در گیتهاب قرار دهیم. حتی میتوان یک branch به پروژه آماده شده برای دپلوی روی هروکو اختصاص داد. سپس از طریق داشبور هروکو مستقیما به گیتهاب وصل شده و پروژه را دپلوی کرد.
اجرا از سرور ریموت
مراحل این روش تا حدود زیادی شبیه روش اول است، چراکه باز نیز با استفاده از flask یک برنامه سرور اجرا میکنیم. برای این روش لازم است از یکی از سرویسهای ارائه دهنده سرورهای ابری (Cloud servers) و یا سرورهای اختصاصی (VPS)، سروری تهیه کنید. پس از تهیه سرور IP ای برای دسترسی به سرور به شما داده میشود. با استفاده از این سرور و از آنجایی که این IP یک IP عمومی (Public IP) است، تنها کافی است با استفاده از فلسک سروری در سیستم اجرا کرده و host آن را برابر ‘0.0.0.0’ قرار دهیم تا از طریق اینترنت قابل دسترس باشد.
ابزارها
Flask – فلسک یک میکروفریمورک سبک برای راهاندازی سریع و راحت وبسرور است. آموزش مقدماتی فلسک را بخوانید.
SSH – پروتکل شبکهای برای اتصال امن که یکی از کاربردهای آن ورود به یک سیستم ریموت است.
برای اتصال به سرور از SSH استفاده میکنیم. برای همین اگر از ویندوز استفاده میکنید از نرمافزار PuTTY استفاده کرده و اگر از لینوکس استفاده میکنید و یا در سیستم ویندوز خود کرنل لینوکس را فعال کردهاید (WSL) -از طریق کرنل لینوکس موجود در سیستم- به آیپی سرور از طریق SSH متصل شوید.
1 |
ssh [Server-IP] |
سپس، پیشنیازهای لازم برای اجرای اسکریپتهای پایتون را نصب کرده و فایلهای لازم برای اجرای مدل شامل، کد اجرای سرور فلسک، فایل مدل و دیگر فایلهای مورد نیاز را به سرور انتقال دهید (از طریق راهاندازی گیت سرور روی سرور و یا آپلود کردن فایلها و دانلود آنها روی سرور).
پس از آن تنها کار لازم اجرای اسکریپت سرور فلسک است. توجه کنیم که برای اجرای سرور فلسک host آنرا برابر ‘0.0.0.0’ و پورت دلخواه (پیش فرض ۵۰۰۰) تنظیم میکنیم:
1 |
app.run(host='0.0.0.0') |
برنامه در آدرس سرور و پورت تعیین شده اجرا شده و از طریق endpointها در دسترس خواهد بود.
منابع
مقالههای «پلوی کردن مدل کراس» و «دپلوی مدلهای کراس» در مدیوم
رپوزیتوری گیت «مثال دپلوی اپلیکیشن پایتون در هروکو»، tl;dr
شبکه های اجتماعی