Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9a2fda7
Add docs/source/ar/pipeline_webserver.md to Add_docs_source_ar_pipeli…
AhmedAlmaghz Aug 22, 2024
1ca6764
Create _toctree.yml
AhmedAlmaghz Sep 16, 2024
1a94839
Update _toctree.yml
AhmedAlmaghz Sep 19, 2024
41d72ef
Update _toctree.yml - tasks_explained
AhmedAlmaghz Sep 22, 2024
7765d6c
Update _toctree.yml - tokenizer_summary
AhmedAlmaghz Sep 24, 2024
5ccdf41
Update _toctree.yml - model_summary
AhmedAlmaghz Sep 24, 2024
e99f0ef
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
e5977e0
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
0931ebd
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
7207537
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
bcf5bab
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
3e9b311
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
775a5e4
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
e274fc7
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
b4393c7
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
fdce305
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
009d23e
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
1c14370
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
7d5d940
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
30def2e
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
5208c4d
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
d7f812c
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
49d1e63
Update docs/source/ar/pipeline_webserver.md
AhmedAlmaghz Sep 27, 2024
75a5f60
Update _toctree.yml - attention
AhmedAlmaghz Sep 27, 2024
9a99d59
Update _toctree.yml - pad_truncation
AhmedAlmaghz Sep 27, 2024
e0f2d6c
Update _toctree.yml - bertology
AhmedAlmaghz Sep 27, 2024
acc1351
Update _toctree.yml - perplexity
AhmedAlmaghz Sep 27, 2024
7bf45cf
Update _toctree.yml - pipeline_webserver
AhmedAlmaghz Sep 27, 2024
7ceddcb
Merge pull request #29 from AhmedAlmaghz/Update_toctree_yml
AhmedAlmaghz Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions docs/source/ar/pipeline_webserver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# استخدام خطوط الأنابيب لخادم ويب
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

<Tip>

إن إنشاء محرك استدلال موضوع معقد، وقد يعتمد "أفضل" حل على مساحة المشكلة لديك. هل أنت على وحدة المعالجة المركزية أو وحدة معالجة الرسومات؟ هل تريد أدنى مستوى من التأخير، أو أعلى مستوى من الإنتاجية، أو دعم العديد من النماذج، أو فقط تحسين نموذج واحد محدد؟ هناك العديد من الطرق لتناول هذا الموضوع، لذا فإن ما سنقدمه هو إعداد افتراضي جيد للبدء، ولكنه قد لا يكون الحل الأمثل بالنسبة لك.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

</Tip>

الشيء الرئيسي الذي يجب فهمه هو أننا يمكن أن نستخدم مؤشرًا، تمامًا كما تفعل [على مجموعة بيانات](pipeline_tutorial#using-pipelines-on-a-dataset)، نظرًا لأن خادم الويب هو أساسًا نظام ينتظر الطلبات ويعالجها عند استلامها.

عادةً ما تكون خوادم الويب متعددة الإرسال (متعددة الخيوط، غير متزامنة، إلخ) للتعامل مع الطلبات المختلفة بشكل متزامن. من ناحية أخرى، فإن خطوط الأنابيب (وبشكل رئيسي النماذج الأساسية) ليست رائعة حقًا للتوازي؛ حيث تستهلك الكثير من ذاكرة الوصول العشوائي، لذا من الأفضل منحها جميع الموارد المتاحة عندما تعمل أو أنها مهمة مكثفة الحساب.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

سنحل ذلك من خلال جعل خادم الويب يتعامل مع الحمل الخفيف لاستقبال الطلبات وإرسالها، ووجود خيط واحد للتعامل مع العمل الفعلي. سيستخدم هذا المثال `starlette`. إطار العمل الفعلي ليس مهمًا حقًا، ولكن قد يتعين عليك ضبط الكود أو تغييره إذا كنت تستخدم إطار عمل آخر لتحقيق نفس التأثير.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

أنشئ `server.py`:

```py
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from transformers import pipeline
import asyncio


async def homepage(request):
payload = await request.body()
string = payload.decode("utf-8")
response_q = asyncio.Queue()
await request.app.model_queue.put((string, response_q))
output = await response_q.get()
return JSONResponse(output)


async def server_loop(q):
pipe = pipeline(model="google-bert/bert-base-uncased")
while True:
(string, response_q) = await q.get()
out = pipe(string)
await response_q.put(out)


app = Starlette(
routes=[
Route("/", homepage, methods=["POST"]),
],
)


@app.on_event("startup")
async def startup_event():
q = asyncio.Queue()
app.model_queue = q
asyncio.create_task(server_loop(q))
```

الآن يمكنك تشغيله باستخدام:

```bash
uvicorn server:app
```

ويمكنك الاستعلام عنه:

```bash
curl -X POST -d "test [MASK]" http://localhost:8000/
#[{"score":0.7742936015129089,"token":1012,"token_str":".","sequence":"test."},...]
```

وهكذا، لديك الآن فكرة جيدة عن كيفية إنشاء خادم ويب!

ما هو مهم حقًا هو أننا نحمل النموذج **مرة واحدة** فقط، لذلك لا توجد نسخ من النموذج على خادم الويب. بهذه الطريقة، لا يتم استخدام ذاكرة الوصول العشوائي غير الضرورية. تسمح آلية وضع الطابور بالقيام بأشياء متقدمة مثل ربما تجميع بعض العناصر قبل الاستدلال لاستخدام الدفعات الديناميكية:
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

<Tip warning={true}>

تم كتابة عينة الكود أدناه بشكل مقصود مثل كود وهمي للقراءة. لا تقم بتشغيله دون التحقق مما إذا كان منطقيًا لموارد النظام الخاص بك!
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

</Tip>

```py
(string, rq) = await q.get()
strings = []
queues = []
while True:
try:
(string, rq) = await asyncio.wait_for(q.get(), timeout=0.001) # 1ms
except asyncio.exceptions.TimeoutError:
break
strings.append(string)
queues.append(rq)
strings
outs = pipe(strings, batch_size=len(strings))
for rq, out in zip(queues, outs):
await rq.put(out)
```

مرة أخرى، تم تحسين الكود المقترح للقراءة، وليس ليكون أفضل كود. أولاً، لا يوجد حد لحجم الدفعة، والذي عادةً ما لا يكون فكرة عظيمة. بعد ذلك، يتم إعادة تعيين المهلة في كل عملية استرداد للصف، مما يعني أنه قد يتعين عليك الانتظار لفترة أطول بكثير من 1 مللي ثانية قبل تشغيل الاستدلال (تأخير الطلب الأول بهذا القدر).
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

سيكون من الأفضل وجود موعد نهائي واحد لمدة 1 مللي ثانية.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

سيظل هذا ينتظر دائمًا لمدة 1 مللي ثانية حتى إذا كان الطابور فارغًا، والذي قد لا يكون الأفضل نظرًا لأنك تريد على الأرجح البدء في إجراء الاستدلال إذا لم يكن هناك شيء في الطابور. ولكن ربما يكون منطقيًا إذا كانت الدفعات مهمة حقًا لحالتك الاستخدام. مرة أخرى، لا يوجد حل واحد الأفضل.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

## بعض الأشياء التي قد ترغب في مراعاتها

### التحقق من الأخطاء

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

من الجيد بشكل عام إذا قام الخادم بإخراج الأخطاء إلى المستخدم، لذا فإن إضافة الكثير من عبارات `try..except` لعرض هذه الأخطاء فكرة جيدة. ولكن ضع في اعتبارك أنه قد يكون أيضًا خطرًا أمنيًا للكشف عن جميع هذه الأخطاء اعتمادًا على سياق الأمان الخاص بك.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

### كسر الدائرة
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

عادةً ما تبدو خوادم الويب أفضل عندما تقوم بكسر الدائرة. وهذا يعني أنها تعيد أخطاء صحيحة عندما تكون مثقلة بالأعباء بدلاً من الانتظار إلى أجل غير مسمى للاستعلام. قم بإرجاع خطأ 503 بدلاً من الانتظار لفترة طويلة جدًا أو 504 بعد فترة طويلة.

من السهل نسبيًا تنفيذ ذلك في الكود المقترح نظرًا لوجود طابور واحد. إن النظر في حجم الطابور هو طريقة أساسية لبدء إعادة الأخطاء قبل فشل خادم الويب بسبب التحميل الزائد.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

### حظر الخيط الرئيسي
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

حاليًا، PyTorch غير مدرك للأساليب غير المتزامنة، وسيؤدي الحساب إلى حظر الخيط الرئيسي أثناء تشغيله. وهذا يعني أنه سيكون من الأفضل إذا تم إجبار PyTorch على التشغيل على خيط/عملية خاصة به. لم يتم ذلك هنا لأن الكود أكثر تعقيدًا (في الغالب لأن الخيوط والأساليب غير المتزامنة والطوابير لا تتوافق معًا). ولكن في النهاية، فإنه يؤدي نفس الوظيفة.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

سيكون هذا مهمًا إذا كان الاستدلال للعناصر الفردية طويلًا (> 1 ثانية) لأنه في هذه الحالة، يجب أن ينتظر كل استعلام أثناء الاستدلال لمدة 1 ثانية قبل حتى تلقي خطأ.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

### الدفعات الديناميكية
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated

بشكل عام، قد لا يكون التجميع تحسينًا بالمقارنة مع تمرير عنصر واحد في كل مرة (راجع [تفاصيل الدفعات](./main_classes/pipelines#pipeline-batching) لمزيد من المعلومات). ولكنه يمكن أن يكون فعالًا جدًا عند استخدامه في الإعداد الصحيح. في واجهة برمجة التطبيقات، لا يوجد تجميع ديناميكي بشكل افتراضي (الكثير من الفرص لتباطؤ). ولكن بالنسبة لاستدلال BLOOM - وهو نموذج كبير جدًا - فإن التجميع الديناميكي **أساسي** لتوفير تجربة جيدة للجميع.
Comment thread
AhmedAlmaghz marked this conversation as resolved.
Outdated