🚀 جرب Zilliz Cloud، الـ Milvus المدارة بالكامل، مجاناً — تجربة أداء أسرع بـ 10 أضعاف! جرب الآن>>

milvus-logo
LFAI
الصفحة الرئيسية
  • عمليات الدمج
    • أخرى
  • Home
  • Docs
  • عمليات الدمج

  • أخرى

  • الذراع

بناء RAG على بنية Arm

يتم استخدام وحدات المعالجة المركزيةArm على نطاق واسع عبر مجموعة واسعة من التطبيقات، بما في ذلك حالات استخدام التعلم الآلي (ML) والذكاء الاصطناعي (AI) التقليدية.

في هذا البرنامج التعليمي، ستتعلم في هذا البرنامج التعليمي كيفية إنشاء تطبيق استرجاع-مُعزَّز (RAG) على البنى التحتية القائمة على الذراع. لتخزين المتجهات، نستخدم Zilliz Cloud، وهي قاعدة بيانات Milvus vector المدارة بالكامل. تتوفر Zilliz Cloud على السحابة الرئيسية مثل AWS وGCP وAzure. في هذا العرض التوضيحي نستخدم Zilliz Cloud المنشورة على AWS مع أجهزة Arm. بالنسبة إلى LLM، نستخدم نموذج Llama-3.1-8B على وحدة المعالجة المركزية للخوادم القائمة على الذراع على AWS باستخدام llama.cpp.

المتطلبات الأساسية

لتشغيل هذا المثال، نوصيك باستخدام AWS Graviton، الذي يوفر طريقة فعالة من حيث التكلفة لتشغيل أعباء عمل التعلم الآلي على الخوادم القائمة على الذراع. تم اختبار هذا الكمبيوتر الدفتري على مثيل AWS Graviton3 c7g.2xlarge مع نظام Ubuntu 22.04 LTS.

تحتاج إلى أربعة أنوية على الأقل وذاكرة وصول عشوائي بسعة 8 جيجابايت لتشغيل هذا المثال. قم بتكوين تخزين القرص حتى 32 جيجابايت على الأقل. نوصي باستخدام مثيل بنفس المواصفات أو أفضل.

بعد تشغيل المثيل، قم بالاتصال به وتشغيل الأوامر التالية لإعداد البيئة.

تثبيت بايثون على الخادم:

$ sudo apt update
$ sudo apt install python-is-python3 python3-pip python3-venv -y

إنشاء بيئة افتراضية وتفعيلها:

$ python -m venv venv
$ source venv/bin/activate

تثبيت تبعيات بايثون المطلوبة:

$ pip install --upgrade pymilvus openai requests langchain-huggingface huggingface_hub tqdm

تحميل البيانات دون اتصال

إنشاء المجموعة

نحن نستخدم Zilliz Cloud المنتشر على AWS مع الأجهزة القائمة على الذراع لتخزين واسترجاع البيانات المتجهة. للبدء سريعًا، ما عليك سوى تسجيل حساب على Zilliz Cloud مجانًا.

وبالإضافة إلى Zilliz Cloud، فإن Milvus المستضاف ذاتيًا هو أيضًا خيار (أكثر تعقيدًا في الإعداد). يمكننا أيضًا نشر Milvus Standalone و Kubernetes على الأجهزة المستندة إلى ARM. لمزيد من المعلومات حول تثبيت Milvus، يرجى الرجوع إلى وثائق التثبيت.

نقوم بتعيين uri و token كنقطة نهاية عامة ومفتاح Api في Zilliz Cloud.

from pymilvus import MilvusClient

milvus_client = MilvusClient(
    uri="<your_zilliz_public_endpoint>", token="<your_zilliz_api_key>"
)

collection_name = "my_rag_collection"

تحقق مما إذا كانت المجموعة موجودة بالفعل وأسقطها إذا كانت موجودة.

if milvus_client.has_collection(collection_name):
    milvus_client.drop_collection(collection_name)

قم بإنشاء مجموعة جديدة بمعلمات محددة.

إذا لم نحدد أي معلومات عن الحقل، سيقوم ميلفوس تلقائيًا بإنشاء حقل افتراضي id للمفتاح الأساسي، وحقل vector لتخزين بيانات المتجه. يتم استخدام حقل JSON محجوز لتخزين الحقول غير المعرفة من قبل الهيكلية وقيمها.

milvus_client.create_collection(
    collection_name=collection_name,
    dimension=384,
    metric_type="IP",  # Inner product distance
    consistency_level="Strong",  # Strong consistency level
)

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

إعداد البيانات

نحن نستخدم صفحات الأسئلة الشائعة من وثائق ميلفوس 2.4.x كمعرفة خاصة في RAG الخاص بنا، وهو مصدر بيانات جيد لخط أنابيب RAG بسيط.

قم بتنزيل الملف المضغوط واستخراج المستندات إلى المجلد milvus_docs.

$ wget https://github.com/milvus-io/milvus-docs/releases/download/v2.4.6-preview/milvus_docs_2.4.x_en.zip
$ unzip -q milvus_docs_2.4.x_en.zip -d milvus_docs

نقوم بتحميل جميع ملفات تخفيض السعر من المجلد milvus_docs/en/faq. بالنسبة لكل مستند، نستخدم ببساطة "# " لفصل المحتوى في الملف، وهو ما يمكن أن يفصل تقريبًا محتوى كل جزء رئيسي من ملف تخفيض السعر.

from glob import glob

text_lines = []

for file_path in glob("milvus_docs/en/faq/*.md", recursive=True):
    with open(file_path, "r") as file:
        file_text = file.read()

    text_lines += file_text.split("# ")

إدراج البيانات

نقوم بإعداد نموذج تضمين بسيط وفعّال في الوقت نفسه كل -MiniLM-L6-v2 يمكنه تحويل النص إلى متجهات تضمين.

from langchain_huggingface import HuggingFaceEmbeddings

embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

قم بتكرار الأسطر النصية وإنشاء التضمينات، ثم قم بإدراج البيانات في ملف Milvus.

هنا حقل جديد text ، وهو حقل غير محدد في مخطط المجموعة. ستتم إضافته تلقائيًا إلى حقل JSON الديناميكي المحجوز، والذي يمكن التعامل معه كحقل عادي على مستوى عالٍ.

from tqdm import tqdm

data = []

text_embeddings = embedding_model.embed_documents(text_lines)

for i, (line, embedding) in enumerate(
    tqdm(zip(text_lines, text_embeddings), desc="Creating embeddings")
):
    data.append({"id": i, "vector": embedding, "text": line})

milvus_client.insert(collection_name=collection_name, data=data)
Creating embeddings: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 72/72 [00:18<00:00,  3.91it/s]

إطلاق خدمة LLM على الذراع

في هذا القسم، سنقوم ببناء وتشغيل خدمة llama.cpp على وحدة المعالجة المركزية القائمة على الذراع.

نموذج Llama 3.1 و llama.cpp

ينتمي نموذج Llama-3.1-8B من Meta إلى عائلة نماذج Llama 3.1 وهو مجاني للاستخدام لأغراض بحثية وتجارية. قبل استخدام النموذج، قم بزيارة موقع Llama على الويب واملأ النموذج لطلب الوصول.

llama.cpp هو مشروع C/C++ المفتوح المصدر الذي يتيح الاستدلال الفعال لنموذج LLM على مجموعة متنوعة من الأجهزة - سواءً محليًا أو في السحابة. يمكنك استضافة نموذج Llama 3.1 بسهولة باستخدام llama.cpp.

قم بتنزيل وبناء llama.cpp

قم بتشغيل الأوامر التالية لتثبيت الأوامر make و cmake و gcc و g++ وغيرها من الأدوات الأساسية المطلوبة لبناء llama.cpp من المصدر:

$ sudo apt install make cmake -y
$ sudo apt install gcc g++ -y
$ sudo apt install build-essential -y

أنت الآن جاهز لبدء البناء llama.cpp.

استنسخ المستودع المصدر ل llama.cpp:

$ git clone https://github.com/ggerganov/llama.cpp

بشكل افتراضي، يتم إنشاء llama.cpp لوحدة المعالجة المركزية فقط على نظامي لينكس وويندوز. لا تحتاج إلى توفير أي مفاتيح إضافية لإنشائه لوحدة المعالجة المركزية Arm التي تقوم بتشغيله عليها.

قم بتشغيل make لبنائه:

$ cd llama.cpp
$ make GGML_NO_LLAMAFILE=1 -j$(nproc)

تحقق من أن llama.cpp قد تم بناؤه بشكل صحيح عن طريق تشغيل أمر المساعدة:

$ ./llama-cli -h

إذا تم بناء llama.cpp بشكل صحيح، فسترى خيار المساعدة معروضًا. يبدو مقتطف الإخراج هكذا:

example usage:

    text generation:     ./llama-cli -m your_model.gguf -p "I believe the meaning of life is" -n 128

    chat (conversation): ./llama-cli -m your_model.gguf -p "You are a helpful assistant" -cnv

يمكنك الآن تنزيل النموذج باستخدام huggingface cli:

$ huggingface-cli download cognitivecomputations/dolphin-2.9.4-llama3.1-8b-gguf dolphin-2.9.4-llama3.1-8b-Q4_0.gguf --local-dir . --local-dir-use-symlinks False

يستخدم تنسيق نموذج GGUF، الذي قدمه فريق llama.cpp، الضغط والتكميم لتقليل دقة الوزن إلى أعداد صحيحة 4 بت، مما يقلل بشكل كبير من المتطلبات الحسابية والذاكرة ويجعل وحدات المعالجة المركزية Arm فعالة في الاستدلال على LLM.

إعادة تكميم أوزان النموذج

لإعادة التكنيز، قم بتشغيل

$ ./llama-quantize --allow-requantize dolphin-2.9.4-llama3.1-8b-Q4_0.gguf dolphin-2.9.4-llama3.1-8b-Q4_0_8_8.gguf Q4_0_8_8

سيؤدي هذا إلى إخراج ملف جديد، dolphin-2.9.4-llama3.1-8b-Q4_0_8_8.gguf ، والذي يحتوي على أوزان معاد تكوينها تسمح llama-cli باستخدام SVE 256 ودعم MATMUL_INT8.

إعادة التهيئة هذه هي الأمثل خصيصًا لـ Graviton3. بالنسبة إلى Graviton2، يجب إجراء إعادة التهيئة المثلى بتنسيق Q4_0_4_4 ، وبالنسبة إلى Graviton4، فإن تنسيق Q4_0_4_8 هو الأنسب لإعادة التهيئة.

بدء تشغيل خدمة LLM

يمكنك استخدام برنامج خادم llama.cpp وإرسال الطلبات عبر واجهة برمجة تطبيقات متوافقة مع OpenAI. يسمح لك هذا بتطوير تطبيقات تتفاعل مع LLM عدة مرات دون الحاجة إلى بدء تشغيله وإيقافه بشكل متكرر. بالإضافة إلى ذلك، يمكنك الوصول إلى الخادم من جهاز آخر حيث يتم استضافة LLM عبر الشبكة.

قم ببدء تشغيل الخادم من سطر الأوامر، ويستمع على المنفذ 8080:

$ ./llama-server -m dolphin-2.9.4-llama3.1-8b-Q4_0_8_8.gguf -n 2048 -t 64 -c 65536  --port 8080
'main: server is listening on 127.0.0.1:8080 - starting the main loop

يمكنك أيضًا ضبط معلمات LLM الذي تم تشغيله لتكييفه مع أجهزة الخادم لديك للحصول على أداء مثالي. لمزيد من المعلومات عن المعلمات، راجع الأمر llama-server --help.

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

لقد قمت ببدء تشغيل خدمة LLM على وحدة المعالجة المركزية القائمة على الذراع. بعد ذلك، نتفاعل مباشرةً مع الخدمة باستخدام OpenAI SDK.

RAG عبر الإنترنت

عميل LLM ونموذج التضمين

نقوم بتهيئة عميل LLM وإعداد نموذج التضمين.

بالنسبة لـ LLM، نستخدم OpenAI SDK لطلب خدمة Llama التي تم إطلاقها من قبل. لا نحتاج إلى استخدام أي مفتاح API لأنه في الواقع خدمة llama.cpp المحلية الخاصة بنا.

from openai import OpenAI

llm_client = OpenAI(base_url="http://localhost:8080/v1", api_key="no-key")

توليد تضمين اختبار وطباعة بُعده والعناصر القليلة الأولى.

test_embedding = embedding_model.embed_query("This is a test")
embedding_dim = len(test_embedding)
print(embedding_dim)
print(test_embedding[:10])
384
[0.03061249852180481, 0.013831384479999542, -0.02084377221763134, 0.016327863559126854, -0.010231520049273968, -0.0479842908680439, -0.017313342541456223, 0.03728749603033066, 0.04588735103607178, 0.034405000507831573]

استرجاع البيانات لاستعلام

لنحدد سؤالًا متكررًا عن ميلفوس.

question = "How is data stored in milvus?"

ابحث عن السؤال في المجموعة واسترجع أفضل 3 مطابقات دلالية.

search_res = milvus_client.search(
    collection_name=collection_name,
    data=[
        embedding_model.embed_query(question)
    ],  # Use the `emb_text` function to convert the question to an embedding vector
    limit=3,  # Return top 3 results
    search_params={"metric_type": "IP", "params": {}},  # Inner product distance
    output_fields=["text"],  # Return the text field
)

لنلقِ نظرة على نتائج البحث عن الاستعلام

import json

retrieved_lines_with_distances = [
    (res["entity"]["text"], res["distance"]) for res in search_res[0]
]
print(json.dumps(retrieved_lines_with_distances, indent=4))
[
    [
        " Where does Milvus store data?\n\nMilvus deals with two types of data, inserted data and metadata. \n\nInserted data, including vector data, scalar data, and collection-specific schema, are stored in persistent storage as incremental log. Milvus supports multiple object storage backends, including [MinIO](https://min.io/), [AWS S3](https://aws.amazon.com/s3/?nc1=h_ls), [Google Cloud Storage](https://cloud.google.com/storage?hl=en#object-storage-for-companies-of-all-sizes) (GCS), [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs), [Alibaba Cloud OSS](https://www.alibabacloud.com/product/object-storage-service), and [Tencent Cloud Object Storage](https://www.tencentcloud.com/products/cos) (COS).\n\nMetadata are generated within Milvus. Each Milvus module has its own metadata that are stored in etcd.\n\n###",
        0.6488019824028015
    ],
    [
        "How does Milvus flush data?\n\nMilvus returns success when inserted data are loaded to the message queue. However, the data are not yet flushed to the disk. Then Milvus' data node writes the data in the message queue to persistent storage as incremental logs. If `flush()` is called, the data node is forced to write all data in the message queue to persistent storage immediately.\n\n###",
        0.5974207520484924
    ],
    [
        "What is the maximum dataset size Milvus can handle?\n\n  \nTheoretically, the maximum dataset size Milvus can handle is determined by the hardware it is run on, specifically system memory and storage:\n\n- Milvus loads all specified collections and partitions into memory before running queries. Therefore, memory size determines the maximum amount of data Milvus can query.\n- When new entities and and collection-related schema (currently only MinIO is supported for data persistence) are added to Milvus, system storage determines the maximum allowable size of inserted data.\n\n###",
        0.5833579301834106
    ]
]

استخدم LLM للحصول على استجابة RAG

تحويل المستندات المسترجعة إلى تنسيق سلسلة.

context = "\n".join(
    [line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]
)
Define system and user prompts for the Language Model. This prompt is assembled with the retrieved documents from Milvus.

SYSTEM_PROMPT = """
Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.
"""
USER_PROMPT = f"""
Use the following pieces of information enclosed in <context> tags to provide an answer to the question enclosed in <question> tags.
<context>
{context}
</context>
<question>
{question}
</question>
"""

استخدم LLM لإنشاء استجابة بناءً على المطالبات. قمنا بتعيين المعلمة model إلى not-used نظرًا لأنها معلمة زائدة عن الحاجة لخدمة llama.cpp.

response = llm_client.chat.completions.create(
    model="not-used",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": USER_PROMPT},
    ],
)
print(response.choices[0].message.content)

Milvus stores data in two types: inserted data and metadata. Inserted data, including vector data, scalar data, and collection-specific schema, are stored in persistent storage as incremental log. Milvus supports multiple object storage backends such as MinIO, AWS S3, Google Cloud Storage (GCS), Azure Blob Storage, Alibaba Cloud OSS, and Tencent Cloud Object Storage (COS). Metadata are generated within Milvus and each Milvus module has its own metadata that are stored in etcd.

تهانينا! لقد قمت ببناء تطبيق RAG فوق البنى التحتية القائمة على الذراع.

جرب Managed Milvus مجاناً

Zilliz Cloud خالي من المتاعب، ويعمل بواسطة Milvus ويعمل بسرعة 10 أضعاف.

ابدأ
التعليقات

هل كانت هذه الصفحة مفيدة؟