🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI
Beranda
  • Integrasi
    • Evaluasi & Keteramatan
  • Home
  • Docs
  • Integrasi

  • Evaluasi & Keteramatan

  • Arize Pheonix

Evaluasi dengan Arize Pheonix

Open In Colab GitHub Repository

Panduan ini mendemonstrasikan cara menggunakan Arize Pheonix untuk mengevaluasi pipeline Retrieval-Augmented Generation (RAG) yang dibangun di atas Milvus.

Sistem RAG menggabungkan sistem pengambilan dengan model generatif untuk menghasilkan teks baru berdasarkan perintah yang diberikan. Sistem ini pertama-tama mengambil dokumen yang relevan dari korpus menggunakan Milvus, dan kemudian menggunakan model generatif untuk menghasilkan teks baru berdasarkan dokumen yang diambil.

Arize Pheonix adalah sebuah kerangka kerja yang membantu Anda mengevaluasi pipeline RAG Anda. Ada alat dan kerangka kerja yang ada yang membantu Anda membangun pipeline ini, tetapi mengevaluasinya dan mengukur kinerja pipeline Anda bisa jadi sulit. Di sinilah Arize Pheonix hadir.

Prasyarat

Sebelum menjalankan notebook ini, pastikan Anda telah menginstal dependensi berikut ini:

$ pip install --upgrade pymilvus openai requests tqdm pandas "arize-phoenix>=4.29.0" nest_asyncio

Jika Anda menggunakan Google Colab, untuk mengaktifkan dependensi yang baru saja terinstal, Anda mungkin perlu memulai ulang runtime (klik menu "Runtime" di bagian atas layar, dan pilih "Restart session" dari menu tarik-turun).

Kita akan menggunakan OpenAI sebagai LLM dalam contoh ini. Anda harus menyiapkan kunci api OPENAI_API_KEY sebagai variabel lingkungan.

import os

# os.environ["OPENAI_API_KEY"] = "sk-*****************"

Mendefinisikan pipeline RAG

Kita akan mendefinisikan kelas RAG yang menggunakan Milvus sebagai penyimpan vektor, dan OpenAI sebagai LLM. Kelas ini berisi metode load, yang memuat data teks ke dalam Milvus, metode retrieve, yang mengambil data teks yang paling mirip dengan pertanyaan yang diberikan, dan metode answer, yang menjawab pertanyaan yang diberikan dengan pengetahuan yang telah diambil.

from typing import List
from tqdm import tqdm
from openai import OpenAI
from pymilvus import MilvusClient


class RAG:
    """
    RAG(Retrieval-Augmented Generation) class built upon OpenAI and Milvus.
    """

    def __init__(self, openai_client: OpenAI, milvus_client: MilvusClient):
        self._prepare_openai(openai_client)
        self._prepare_milvus(milvus_client)

    def _emb_text(self, text: str) -> List[float]:
        return (
            self.openai_client.embeddings.create(input=text, model=self.embedding_model)
            .data[0]
            .embedding
        )

    def _prepare_openai(
        self,
        openai_client: OpenAI,
        embedding_model: str = "text-embedding-3-small",
        llm_model: str = "gpt-4o-mini",
    ):
        self.openai_client = openai_client
        self.embedding_model = embedding_model
        self.llm_model = llm_model
        self.SYSTEM_PROMPT = """
            Human: You are an AI assistant. You are able to find answers to the questions from the contextual passage snippets provided.
        """
        self.USER_PROMPT = """
            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>
        """

    def _prepare_milvus(
        self, milvus_client: MilvusClient, collection_name: str = "rag_collection"
    ):
        self.milvus_client = milvus_client
        self.collection_name = collection_name
        if self.milvus_client.has_collection(self.collection_name):
            self.milvus_client.drop_collection(self.collection_name)
        embedding_dim = len(self._emb_text("demo"))
        self.milvus_client.create_collection(
            collection_name=self.collection_name,
            dimension=embedding_dim,
            metric_type="IP",
            consistency_level="Strong",
        )

    def load(self, texts: List[str]):
        """
        Load the text data into Milvus.
        """
        data = []
        for i, line in enumerate(tqdm(texts, desc="Creating embeddings")):
            data.append({"id": i, "vector": self._emb_text(line), "text": line})
        self.milvus_client.insert(collection_name=self.collection_name, data=data)

    def retrieve(self, question: str, top_k: int = 3) -> List[str]:
        """
        Retrieve the most similar text data to the given question.
        """
        search_res = self.milvus_client.search(
            collection_name=self.collection_name,
            data=[self._emb_text(question)],
            limit=top_k,
            search_params={"metric_type": "IP", "params": {}},  # inner product distance
            output_fields=["text"],  # Return the text field
        )
        retrieved_texts = [res["entity"]["text"] for res in search_res[0]]
        return retrieved_texts[:top_k]

    def answer(
        self,
        question: str,
        retrieval_top_k: int = 3,
        return_retrieved_text: bool = False,
    ):
        """
        Answer the given question with the retrieved knowledge.
        """
        retrieved_texts = self.retrieve(question, top_k=retrieval_top_k)
        user_prompt = self.USER_PROMPT.format(
            context="\n".join(retrieved_texts), question=question
        )
        response = self.openai_client.chat.completions.create(
            model=self.llm_model,
            messages=[
                {"role": "system", "content": self.SYSTEM_PROMPT},
                {"role": "user", "content": user_prompt},
            ],
        )
        if not return_retrieved_text:
            return response.choices[0].message.content
        else:
            return response.choices[0].message.content, retrieved_texts

Mari kita inisialisasi kelas RAG dengan klien OpenAI dan Milvus.

openai_client = OpenAI()
milvus_client = MilvusClient(uri="./milvus_demo.db")

my_rag = RAG(openai_client=openai_client, milvus_client=milvus_client)

Adapun argumen dari MilvusClient:

  • Menetapkan uri sebagai file lokal, misalnya./milvus.db, adalah metode yang paling mudah, karena secara otomatis menggunakan Milvus Lite untuk menyimpan semua data dalam file ini.
  • Jika Anda memiliki data dalam skala besar, Anda dapat mengatur server Milvus yang lebih berkinerja pada docker atau kubernetes. Dalam pengaturan ini, silakan gunakan uri server, misalnyahttp://localhost:19530, sebagai uri.
  • Jika Anda ingin menggunakan Zilliz Cloud, layanan cloud yang dikelola sepenuhnya untuk Milvus, sesuaikan uri dan token, yang sesuai dengan kunci Public Endpoint dan Api di Zilliz Cloud.

Jalankan pipeline RAG dan dapatkan hasilnya

Kami menggunakan panduan pengembangan Milvus sebagai pengetahuan pribadi dalam RAG kami, yang merupakan sumber data yang baik untuk pipeline RAG sederhana.

Unduh dan muat ke dalam pipeline RAG.

import urllib.request
import os

url = "https://raw.githubusercontent.com/milvus-io/milvus/master/DEVELOPMENT.md"
file_path = "./Milvus_DEVELOPMENT.md"

if not os.path.exists(file_path):
    urllib.request.urlretrieve(url, file_path)
with open(file_path, "r") as file:
    file_text = file.read()

text_lines = file_text.split("# ")
my_rag.load(text_lines)
Creating embeddings: 100%|██████████| 47/47 [00:12<00:00,  3.84it/s]

Mari kita mendefinisikan pertanyaan kueri tentang konten dokumentasi panduan pengembangan. Lalu gunakan metode answer untuk mendapatkan jawaban dan teks konteks yang diambil.

question = "what is the hardware requirements specification if I want to build Milvus and run from source code?"
my_rag.answer(question, return_retrieved_text=True)
('The hardware requirements specification to build and run Milvus from source code are:\n\n- 8GB of RAM\n- 50GB of free disk space',
 ['Hardware Requirements\n\nThe following specification (either physical or virtual machine resources) is recommended for Milvus to build and run from source code.\n\n```\n- 8GB of RAM\n- 50GB of free disk space\n```\n\n##',
  'Building Milvus on a local OS/shell environment\n\nThe details below outline the hardware and software requirements for building on Linux and MacOS.\n\n##',
  "Software Requirements\n\nAll Linux distributions are available for Milvus development. However a majority of our contributor worked with Ubuntu or CentOS systems, with a small portion of Mac (both x86_64 and Apple Silicon) contributors. If you would like Milvus to build and run on other distributions, you are more than welcome to file an issue and contribute!\n\nHere's a list of verified OS types where Milvus can successfully build and run:\n\n- Debian/Ubuntu\n- Amazon Linux\n- MacOS (x86_64)\n- MacOS (Apple Silicon)\n\n##"])

Sekarang mari kita siapkan beberapa pertanyaan dengan jawaban ground truth yang sesuai. Kita mendapatkan jawaban dan konteks dari pipeline RAG kita.

from datasets import Dataset
import pandas as pd

question_list = [
    "what is the hardware requirements specification if I want to build Milvus and run from source code?",
    "What is the programming language used to write Knowhere?",
    "What should be ensured before running code coverage?",
]
ground_truth_list = [
    "If you want to build Milvus and run from source code, the recommended hardware requirements specification is:\n\n- 8GB of RAM\n- 50GB of free disk space.",
    "The programming language used to write Knowhere is C++.",
    "Before running code coverage, you should make sure that your code changes are covered by unit tests.",
]
contexts_list = []
answer_list = []
for question in tqdm(question_list, desc="Answering questions"):
    answer, contexts = my_rag.answer(question, return_retrieved_text=True)
    contexts_list.append(contexts)
    answer_list.append(answer)

df = pd.DataFrame(
    {
        "question": question_list,
        "contexts": contexts_list,
        "answer": answer_list,
        "ground_truth": ground_truth_list,
    }
)
rag_results = Dataset.from_pandas(df)
df
/Users/eureka/miniconda3/envs/zilliz/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
Answering questions: 100%|██████████| 3/3 [00:03<00:00,  1.04s/it]
pertanyaan konteks jawaban ground_truth
0 apa spesifikasi kebutuhan perangkat keras yang ... [Persyaratan Perangkat Keras\n\nSpesifikasi berikut ini adalah spesifikasi ... Spesifikasi persyaratan perangkat keras untuk membangun ... Jika Anda ingin membangun Milvus dan menjalankannya dari sumber ...
1 Apa bahasa pemrograman yang digunakan untuk menulis ... [CMake & Conan\n\nPustaka algoritme dari Mil... Bahasa pemrograman yang digunakan untuk menulis Knowher... Bahasa pemrograman yang digunakan untuk menulis Knowher...
2 Apa yang harus dipastikan sebelum menjalankan cakupan kode ... [Cakupan kode\n\nSebelum mengirimkan pull ... Sebelum menjalankan cakupan kode, Anda harus memastikan ... Sebelum menjalankan cakupan kode, Anda harus membuat ...

Evaluasi dengan Arize Phoenix

Kami menggunakan Arize Phoenix untuk mengevaluasi pipeline retrieval-augmented generation (RAG) kami, dengan fokus pada dua metrik utama:

  • Evaluasi Halusinasi: Menentukan apakah konten tersebut faktual atau halusinasi (informasi yang tidak sesuai dengan konteks), untuk memastikan integritas data.

    • Penjelasan Halusinasi: Menjelaskan mengapa suatu tanggapan bersifat faktual atau tidak.
  • Evaluasi QA: Menilai keakuratan jawaban model terhadap pertanyaan masukan.

    • Penjelasan QA: Merinci mengapa suatu jawaban benar atau salah.

Ikhtisar Penelusuran Phoenix

Phoenix menyediakan penelusuran yang kompatibel dengan OTEL untuk aplikasi LLM, dengan integrasi untuk kerangka kerja seperti Langchain, LlamaIndex, dan SDK seperti OpenAI dan Mistral. Penelusuran menangkap seluruh aliran permintaan, menawarkan wawasan ke dalam:

  • Latensi Aplikasi: Mengidentifikasi dan mengoptimalkan panggilan LLM yang lambat dan kinerja komponen.
  • Penggunaan Token: Memecah konsumsi token untuk pengoptimalan biaya.
  • Pengecualian Runtime: Menangkap masalah kritis seperti pembatasan kecepatan.
  • Dokumen yangDiambil: Menganalisis pengambilan dokumen, skor, dan urutan.

Dengan memanfaatkan penelusuran Phoenix, Anda dapat mengidentifikasi kemacetan, mengoptimalkan sumber daya, dan memastikan keandalan sistem di berbagai kerangka kerja dan bahasa.

import phoenix as px
from phoenix.trace.openai import OpenAIInstrumentor

# To view traces in Phoenix, you will first have to start a Phoenix server. You can do this by running the following:
session = px.launch_app()

# Initialize OpenAI auto-instrumentation
OpenAIInstrumentor().instrument()
🌍 To view the Phoenix app in your browser, visit http://localhost:6006/
📖 For more information on how to use Phoenix, check out https://docs.arize.com/phoenix

Alt Text Alt Text

import nest_asyncio

from phoenix.evals import HallucinationEvaluator, OpenAIModel, QAEvaluator, run_evals

nest_asyncio.apply()  # This is needed for concurrency in notebook environments

# Set your OpenAI API key
eval_model = OpenAIModel(model="gpt-4o")

# Define your evaluators
hallucination_evaluator = HallucinationEvaluator(eval_model)
qa_evaluator = QAEvaluator(eval_model)

# We have to make some minor changes to our dataframe to use the column names expected by our evaluators
# for `hallucination_evaluator` the input df needs to have columns 'output', 'input', 'context'
# for `qa_evaluator` the input df needs to have columns 'output', 'input', 'reference'
df["context"] = df["contexts"]
df["reference"] = df["contexts"]
df.rename(columns={"question": "input", "answer": "output"}, inplace=True)
assert all(
    column in df.columns for column in ["output", "input", "context", "reference"]
)

# Run the evaluators, each evaluator will return a dataframe with evaluation results
# We upload the evaluation results to Phoenix in the next step
hallucination_eval_df, qa_eval_df = run_evals(
    dataframe=df,
    evaluators=[hallucination_evaluator, qa_evaluator],
    provide_explanation=True,
)
run_evals |██████████| 6/6 (100.0%) | ⏳ 00:03<00:00 |  1.64it/s
results_df = df.copy()
results_df["hallucination_eval"] = hallucination_eval_df["label"]
results_df["hallucination_explanation"] = hallucination_eval_df["explanation"]
results_df["qa_eval"] = qa_eval_df["label"]
results_df["qa_explanation"] = qa_eval_df["explanation"]
results_df.head()
input konteks keluaran ground_truth konteks referensi evaluasi_halusinasi penjelasan_halusinasi qa_eval qa_eksplanasi
0 apa spesifikasi persyaratan perangkat keras ... [Persyaratan Perangkat Keras\n\nSpesifikasi berikut ini adalah spesifikasi ... Spesifikasi kebutuhan perangkat keras untuk membangun ... Jika Anda ingin membuat Milvus dan menjalankannya dari sumber ... [Persyaratan Perangkat Keras] Spesifikasi berikut ini untuk membangun ... [Persyaratan Perangkat Keras\n\nSpesifikasi berikut ini untuk membangun ... faktual Untuk menentukan apakah jawaban tersebut faktual atau halus... benar Untuk menentukan apakah jawabannya benar, kita perlu...
1 Apa bahasa pemrograman yang digunakan untuk menulis ... [CMake & Conan\n\nPustaka algoritma dari Mil... Bahasa pemrograman yang digunakan untuk menulis Knowher... Bahasa pemrograman yang digunakan untuk menulis Knowher... [CMake & Conan\n\nPustaka algoritma dari Mil... [CMake & Conan\n\nPustaka algoritma dari Mil... faktual Untuk menentukan apakah jawaban tersebut faktual atau halus... benar Untuk menentukan apakah jawabannya benar, kita perlu...
2 Apa yang harus dipastikan sebelum menjalankan cakupan kode ... [Cakupan kode\n\nSebelum mengirimkan pull ... Sebelum menjalankan cakupan kode, Anda harus memastikan ... Sebelum menjalankan cakupan kode, Anda harus membuat ... [Cakupan kode\n\nSebelum mengirimkan pull ... [Cakupan kode\n\nSebelum mengirimkan pull ... faktual Teks referensi menentukan bahwa sebelum menjalankan ... benar Untuk menentukan apakah jawabannya benar, kita perlu...

Coba Milvus yang Dikelola secara Gratis

Zilliz Cloud bebas masalah, didukung oleh Milvus dan 10x lebih cepat.

Mulai
Umpan balik

Apakah halaman ini bermanfaat?