diff --git a/.gitignore b/.gitignore
index 0b8d49f9b..bb94808bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -167,3 +167,17 @@ xcuserdata/
*.pte
*.model
Package.resolved
+
+#embeddings
+**/faiss_index.index
+**/faiss_index.index.json
+**/chroma
+
+
+# DocQA
+/examples/DocQA/data/input
+/examples/DocQA/data/output
+**/.gradio
+**/RAG_service.json
+examples/DocQA/example_data/chroma.sqlite3
+examples/DocQA/example_data/**/*.bin
diff --git a/examples/DocQA/README.md b/examples/DocQA/README.md
new file mode 100644
index 000000000..7b8cfee31
--- /dev/null
+++ b/examples/DocQA/README.md
@@ -0,0 +1,51 @@
+## DocQA
+
+This is an end-to-end Retrieval Augmented Generation (RAG) App leveraging llama-stack that handles the logic for ingesting documents, storing them in a vector database and providing an inference interface.
+
+We share the details of how to run first and then an outline of how it works:
+
+### Prerequisite:
+
+Install docker: Check [this doc for Mac](https://docs.docker.com/desktop/setup/install/mac-install/), [this doc for Windows](https://docs.docker.com/desktop/setup/install/windows-install/) and this [instruction for Linux](https://docs.docker.com/engine/install/).
+
+For Mac and Windows users, you need to start the Docker app manually after installation.
+
+### How to run the pipeline:
+
+
+
+The above is the workflow diagram for this RAG app. To run the app, please read the following instructions:
+
+1. Copy the template configuration file `docqa_env_template` to create your own `docqv_env` inside the docker folder:
+
+```bash
+cd docker
+cp docqa_env_template docqv_env
+```
+
+2. Then update `model_name` and `document_path` accordingly in your `docqv_env`, for example:
+
+```
+DOC_PATH=/path/to/your/llama-stack-apps/examples/DocQA/example_data
+MODEL_NAME=llama3.2:1b-instruct-fp16
+HOST=localhost
+LLAMA_STACK_PORT=5000
+CHROMA_PORT=6000
+GRADIO_SERVER_PORT=7860
+USE_GPU_FOR_DOC_INGESTION=false
+```
+
+3. In the `docker` folder, run following code:
+
+```bash
+bash run_RAG.sh
+```
+
+4. Once the service is ready, open the link http://localhost:7861/ in your browser to chat with your documents.
+
+### Overview of how the RAG app works:
+
+1. We use [docling](https://github.com/DS4SD/docling) framework for handling multiple file input formats (PDF, PPTX, DOCX)
+2. If you are using a GPU, we have an option to use `Llama-3.2-11B-Vision` to caption images in the documents. On a CPU-only machine this step is skipped.
+3. Once ingested, we use a llama-stack distribution running chroma-db and `Llama-3.2-3B-Instruct` to ingest chunks into a memory_bank
+4. Once the vectordb is created, we then use llama-stack with the `Llama-3.2-3B-Instruct` to chat with the model.
diff --git a/examples/DocQA/app.py b/examples/DocQA/app.py
new file mode 100644
index 000000000..3eff8fa52
--- /dev/null
+++ b/examples/DocQA/app.py
@@ -0,0 +1,301 @@
+import asyncio
+import json
+import os
+import re
+import uuid
+from queue import Queue
+from threading import Thread
+from typing import AsyncGenerator, Generator, List, Optional
+
+import chromadb
+import gradio as gr
+import requests
+from chromadb.utils import embedding_functions
+from dotenv import load_dotenv
+from llama_stack_client import LlamaStackClient
+from llama_stack_client.lib.agents.agent import Agent
+from llama_stack_client.lib.agents.event_logger import EventLogger
+from llama_stack_client.types.agent_create_params import AgentConfig
+from llama_stack_client.types.memory_insert_params import Document
+
+
+# Load environment variables
+load_dotenv()
+
+HOST = os.getenv("HOST", "localhost")
+LLAMA_STACK_PORT = int(os.getenv("LLAMA_STACK_PORT", "5000"))
+GRADIO_SERVER_PORT = int(os.getenv("GRADIO_SERVER_PORT", "7861"))
+USE_GPU_FOR_DOC_INGESTION = os.getenv("USE_GPU_FOR_DOC_INGESTION", False)
+MODEL_NAME = os.getenv("MODEL_NAME", "meta-llama/Llama-3.2-1B-Instruct")
+# if USE_GPU_FOR_DOC_INGESTION, then the documents will be processed to output folder
+DOCS_DIR = "/root/rag_data/output" if USE_GPU_FOR_DOC_INGESTION else "/root/rag_data/"
+
+CUSTOM_CSS = """
+.context-block {
+ font-size: 0.8em;
+ border-left: 3px solid #e9ecef;
+ margin: 0.5em 0;
+ padding: 0.5em 1em;
+ opacity: 0.85;
+}
+
+.context-title {
+ font-size: 0.8em;
+ color: #9ca3af;
+ font-weight: 400;
+ display: flex;
+ align-items: center;
+ gap: 0.5em;
+ margin-bottom: 0.3em;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.context-title::before {
+ content: "📄";
+ font-size: 1em;
+ opacity: 0.7;
+}
+
+.context-content {
+ color: #6b7280;
+ line-height: 1.4;
+ font-weight: 400;
+}
+
+.inference-response {
+ font-size: 1em;
+ color: #111827;
+ line-height: 1.5;
+ margin-top: 1em;
+}
+"""
+
+
+class LlamaChatInterface:
+ def __init__(self, host: str, port: int, docs_dir: str):
+ self.host = host
+ self.port = port
+ self.docs_dir = docs_dir
+ self.client = LlamaStackClient(base_url=f"http://{host}:{port}")
+ self.agent = None
+ self.session_id = None
+ self.memory_bank_id = "docqa_bank"
+
+ async def initialize_system(self):
+ """Initialize the entire system including memory bank and agent."""
+ await self.setup_memory_bank()
+ await self.initialize_agent()
+
+ async def setup_memory_bank(self):
+ """Set up the memory bank if it doesn't exist."""
+ providers = self.client.providers.list()
+ provider_id = providers["memory"][0].provider_id
+ memory_banks = self.client.memory_banks.list()
+ print(f"Memory banks: {memory_banks}")
+
+ # Check if memory bank exists by identifier
+ if any(bank.identifier == self.memory_bank_id for bank in memory_banks):
+ print(f"Memory bank '{self.memory_bank_id}' exists.")
+ else:
+ print(f"Memory bank '{self.memory_bank_id}' does not exist. Creating...")
+ self.client.memory_banks.register(
+ memory_bank_id=self.memory_bank_id,
+ params={
+ "embedding_model": "all-MiniLM-L6-v2",
+ "chunk_size_in_tokens": 100,
+ "overlap_size_in_tokens": 10,
+ },
+ provider_id=provider_id,
+ )
+ await self.load_documents()
+ print(f"Memory bank registered.")
+
+ async def load_documents(self):
+ """Load documents from the specified directory into memory bank."""
+ documents = []
+ for filename in os.listdir(self.docs_dir):
+ if filename.endswith((".txt", ".md")):
+ file_path = os.path.join(self.docs_dir, filename)
+ with open(file_path, "r", encoding="utf-8") as file:
+ content = file.read()
+ document = Document(
+ document_id=filename,
+ content=content,
+ mime_type="text/plain",
+ metadata={"filename": filename},
+ )
+ documents.append(document)
+
+ if documents:
+ self.client.memory.insert(
+ bank_id=self.memory_bank_id,
+ documents=documents,
+ )
+ print(f"Loaded {len(documents)} documents from {self.docs_dir}")
+
+ async def initialize_agent(self):
+ """Initialize the agent with model registration and configuration."""
+
+ if "1b" in MODEL_NAME:
+ model_name = "Llama3.2-1B-Instruct"
+ elif "3b" in MODEL_NAME:
+ model_name = "Llama3.2-3B-Instruct"
+ elif "8b" in MODEL_NAME:
+ model_name = "Llama3.1-8B-Instruct"
+ else:
+ model_name = MODEL_NAME
+
+ agent_config = AgentConfig(
+ model=model_name,
+ instructions="You are a helpful assistant that can answer questions based on provided documents. Return your answer short and concise, less than 50 words.",
+ sampling_params={"strategy": "greedy", "temperature": 1.0, "top_p": 0.9},
+ tools=[
+ {
+ "type": "memory",
+ "memory_bank_configs": [
+ {"bank_id": self.memory_bank_id, "type": "vector"}
+ ],
+ "max_tokens_in_context": 300,
+ "max_chunks": 5,
+ }
+ ],
+ tool_choice="auto",
+ tool_prompt_format="json",
+ enable_session_persistence=True,
+ )
+ self.agent = Agent(self.client, agent_config)
+ self.session_id = self.agent.create_session(f"session-{uuid.uuid4()}")
+
+ def chat_stream(
+ self, message: str, history: List[List[str]]
+ ) -> Generator[List[List[str]], None, None]:
+ """Stream chat responses token by token with proper history handling."""
+
+ history = history or []
+ history.append([message, ""])
+
+ if self.agent is None:
+ asyncio.run(self.initialize_system())
+
+ response = self.agent.create_turn(
+ messages=[{"role": "user", "content": message}],
+ session_id=self.session_id,
+ )
+
+ current_response = ""
+ context_shown = False
+
+ for log in EventLogger().log(response):
+ log.print()
+ if hasattr(log, "content"):
+ # Format context blocks if present
+ if not context_shown and "Retrieved context from banks" in str(log):
+ context = self.format_context(str(log))
+ current_response = context + current_response
+ context_shown = True
+ else:
+ current_response += log.content
+
+ history[-1][1] = current_response
+ yield history.copy()
+
+ def format_context(self, log_str: str) -> str:
+ """Format the context block with custom styling."""
+ # Extract context and clean up the markers
+ context_match = re.search(
+ r"Retrieved context from banks:.*?\n(.*?===.*?===.*?)(?=\n>|$)",
+ log_str,
+ re.DOTALL,
+ )
+ if context_match:
+ context = context_match.group(1).strip()
+ # Remove the marker lines
+ context = re.sub(
+ r"====\s*Here are the retrieved documents for relevant context:\s*===\s*START-RETRIEVED-CONTEXT\s*===\s*",
+ "",
+ context,
+ flags=re.IGNORECASE,
+ )
+ return f"""
+
+
Retrieved Context
+
{context}
+
+"""
+ return ""
+
+
+def create_gradio_interface(
+ host: str = HOST,
+ port: int = LLAMA_STACK_PORT,
+ docs_dir: str = DOCS_DIR,
+):
+ chat_interface = LlamaChatInterface(host, port, docs_dir)
+
+ with gr.Blocks(theme=gr.themes.Soft(), css=CUSTOM_CSS) as interface:
+ gr.Markdown("# LlamaStack Chat")
+
+ chatbot = gr.Chatbot(
+ bubble_full_width=False,
+ show_label=False,
+ height=400,
+ container=True,
+ render_markdown=True,
+ )
+ msg = gr.Textbox(
+ label="Message",
+ placeholder="Type your message here...",
+ show_label=False,
+ container=False,
+ )
+ with gr.Row():
+ submit = gr.Button("Send", variant="primary")
+ clear = gr.Button("Clear")
+
+ gr.Examples(
+ examples=[
+ "What topics are covered in the documents?",
+ "Can you summarize the main points?",
+ "Tell me more about specific details in the text.",
+ ],
+ inputs=msg,
+ )
+
+ def clear_chat():
+ return [], ""
+
+ submit_event = msg.submit(
+ fn=chat_interface.chat_stream,
+ inputs=[msg, chatbot],
+ outputs=chatbot,
+ queue=True,
+ ).then(
+ fn=lambda: "",
+ outputs=msg,
+ )
+
+ submit_click = submit.click(
+ fn=chat_interface.chat_stream,
+ inputs=[msg, chatbot],
+ outputs=chatbot,
+ queue=True,
+ ).then(
+ fn=lambda: "",
+ outputs=msg,
+ )
+
+ clear.click(clear_chat, outputs=[chatbot, msg], queue=False)
+
+ msg.submit(lambda: None, None, None, api_name=False)
+ interface.load(fn=chat_interface.initialize_system)
+
+ return interface
+
+
+if __name__ == "__main__":
+ # Create and launch the Gradio interface
+ interface = create_gradio_interface()
+ interface.launch(
+ server_name=HOST, server_port=GRADIO_SERVER_PORT, share=True, debug=True
+ )
diff --git a/examples/DocQA/data/assets/DocQA.png b/examples/DocQA/data/assets/DocQA.png
new file mode 100644
index 000000000..4d922b9e4
Binary files /dev/null and b/examples/DocQA/data/assets/DocQA.png differ
diff --git a/examples/DocQA/data/eval/.env.template b/examples/DocQA/data/eval/.env.template
new file mode 100644
index 000000000..304e30e2d
--- /dev/null
+++ b/examples/DocQA/data/eval/.env.template
@@ -0,0 +1,14 @@
+# Server Configuration
+HOST=localhost
+PORT=5000
+CHROMA_PORT=8000
+
+# Model and Memory Configuration
+MODEL_NAME=meta-llama/Llama-3.2-3B-Instruct
+MEMORY_BANK_ID=eval_bank
+
+# File Paths
+DOCS_DIR=../output
+
+# Optional: Add your API keys here if needed
+# OPENAI_API_KEY=your_api_key_here
diff --git a/examples/DocQA/data/eval/QA_eval.json b/examples/DocQA/data/eval/QA_eval.json
new file mode 100644
index 000000000..664bff1e2
--- /dev/null
+++ b/examples/DocQA/data/eval/QA_eval.json
@@ -0,0 +1,102 @@
+[
+ {
+ "Question": "What is the policy regarding smoking in City offices?",
+ "Answer": "Smoking is not permitted in City offices, or within 20 feet of entrances, exits, or operable windows of public buildings. (Source: Page 46, 'Smoke-Free Workplace' section)"
+ },
+ {
+ "Question": "How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules?",
+ "Answer": "Most full-time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. (Source: Page 32, 'Accrual of Paid Sick Leave' section)"
+ },
+ {
+ "Question": "What are the three categories of employees eligible for health coverage?",
+ "Answer": "The following employees are eligible:\n\nAll permanent employees working at least 20 hours per week\n\nAll regularly scheduled provisional employees working at least 20 hours per week\n\nAll other employees (including temporary exempt or 'as needed') who have worked more than 1040 hours in any consecutive 12-month period and work at least 20 hours per week (Source: Page 25, 'Eligibility' section)"
+ },
+ {
+ "Question": "How long must an employee wait before using vacation time after starting employment?",
+ "Answer": "Employees are not eligible to use vacation in the first year of continuous service. After one year of continuous service, they are awarded vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year. (Source: Page 30, 'Vacation' section)"
+ },
+ {
+ "Question": "What must an employee do if they're summoned for jury duty?",
+ "Answer": "An employee must notify their supervisor as soon as they receive a jury summons. If required to report during working hours, they will be excused from work on the day they perform jury service, provided they give prior notification. If not selected or dismissed early, they must return to work as soon as possible. (Source: Page 37, 'Jury Duty Leave' section)"
+ },
+ {
+ "Question": "What happens if an employee is absent without authorization for more than five consecutive working days?",
+ "Answer": "If an employee is absent from their job without proper authorization for more than five consecutive working days, or fails to return from an approved leave, their absence will be deemed an 'automatic resignation.' (Source: Page 19, 'Automatic Resignation' section)"
+ },
+ {
+ "Question": "How long is the normal probationary period for permanent civil service positions?",
+ "Answer": "The document states that all appointments to permanent civil service positions require a probationary period, but the duration is governed by the collective bargaining agreement. Absences from work will extend the probationary period. (Source: Page 14, 'Probationary Period' section)"
+ },
+ {
+ "Question": "What are employees required to do in case of a catastrophic event while off duty?",
+ "Answer": "Employees should ensure the safety of their family and follow their department's instructions. If phone lines are down, they are required to listen to the radio for any reporting instructions. (Source: Page 51, 'Catastrophic Event While off Duty' section)"
+ },
+ {
+ "Question": "What is the city's policy on accepting gifts from subordinates?",
+ "Answer": "Employees may not solicit or accept any gifts from any subordinate, or any candidate or applicant for a position as an employee or subordinate to them. (Source: Page 49, 'Gifts' section)"
+ },
+ {
+ "Question": "What documents must new employees present at the time of hire?",
+ "Answer": "New employees must present:\n\nSocial Security number\n\nDocuments to verify identity and authorization to work in the United States\n\nTake the Oath of Office\n\nSign acknowledgment of no-strike provision\n\nComplete tax forms (W-4)\n\nComplete Warrant Recipient Form (Source: Pages 11-12, 'Requirements at the Time of Hire' section)"
+ },
+ {
+ "Question": "What are the fees for a new Special Traffic Permit in San Francisco?",
+ "Answer": "New Special Traffic Permits cost $388 processing fee plus $78 per day."
+ },
+ {
+ "Question": "During what hours does the Holiday Moratorium restrict construction work in San Francisco?",
+ "Answer": "No construction work is allowed in the public right of way from the day after Thanksgiving to January 1, inclusive, during the hours of 7 a.m. to 10 p.m. on Holiday Moratorium protected streets."
+ },
+ {
+ "Question": "How many days in advance must contractors register tow-away signs with SFMTA?",
+ "Answer": "Tow-Away signs must be posted and registered with the SFMTA Tow-Desk or SF Public Works online at least 72 hours prior to the enforcement date."
+},
+{
+ "Question": "What is the minimum width required for a single traffic lane in San Francisco?",
+ "Answer": "The minimum width required for a single traffic lane is 12 feet. The minimum width required for a vehicular traffic lane contiguous to one or more vehicular traffic lanes in the same direction is 10 feet."
+},
+{
+ "Question": "What clearance must equipment maintain from Muni overhead electric wires?",
+ "Answer": "CAL OSHA and CPUC General Order 95 regulations require that any boom type equipment that moves vertically must maintain a 10 feet radial clearance and any other equipment must maintain a six (6) foot clearance from Muni overhead wires."
+},
+{
+ "Question": "What restrictions apply around Oracle Park during events?",
+ "Answer": "No construction activity is allowed from two (2) hours before to two (2) hours after these events around Oracle Park."
+},
+{
+ "Question": "What is the minimum processing time required for new Special Traffic Permits?",
+ "Answer": "New permits may require five (5) working days. More complicated requests may take longer. Very complex permit applications, such as Tower Crane Erections, Concrete Mat Pours and Complex road closures require a minimum of 8 weeks processing time."
+},
+{
+ "Question": "What is the minimum clear path of travel required on sidewalks during construction?",
+ "Answer": "A 6-foot wide clear path of travel is desirable. At a minimum, Contractor shall provide a 4-foot wide clear path of travel on any sidewalk at all times."
+},
+{
+ "Question": "What are the main functions of the Legislative Department regarding Bills?",
+ "Answer": "According to Section 1.1(ii) of the document, the Legislative Department's main functions regarding Bills include: 'Drafting and scrutiny of all Government Bills including Constitution (Amendment) Bills, translation of all the Bills into Hindi and forwarding of both English and Hindi versions of the Bills to the Lok Sabha or Rajya Sabha Secretariat for introduction in Parliament; drafting of official amendments to the Bills; scrutiny of non-official amendments and rendering assistance to administrative Ministries/Departments to decide the acceptability or otherwise of non-official amendments.'"
+},
+{
+ "Question": "How many Bills were forwarded to Parliament for introduction during the period from January 1, 2021 to December 31, 2021?",
+ "Answer": "According to Section 4 of the document, 50 Legislative Bills were forwarded to Parliament for introduction during this period. The exact quote states: '50 Legislative Bills were forwarded to Parliament for introduction during this period.'"
+},
+{
+ "Question": "What is the role of the Official Languages Wing regarding legal terminology?",
+ "Answer": "According to Section 41(1)(i) of the document, the Official Languages Wing is responsible for 'Preparation and publication of a standard legal terminology for use, as far as possible, in all Official Languages.' The Wing has published seven editions of Legal Glossary, with the latest 7th Edition containing approximately 65,000 entries."
+},
+{
+ "Question": "How does the Legislative Department handle public grievances?",
+ "Answer": "According to Section 45 of the document, 'During the period from 1st January, 2021 to 31st December, 2021 Legislative Department received 1644 public grievances on CPGRAMS portal. Further 223 public grievances were pending before 1st January, 2021. During the said period 1544 grievances have been disposed off and action is being taken for disposal of remaining grievances on priority basis.'"
+},
+{
+ "Question": "What are the provisions for linking electoral rolls with Aadhaar according to the Election Laws (Amendment) Act, 2021?",
+ "Answer": "According to Section 22.1 of the document, 'The newly passed Election Laws (Amendment) Act, 2021 amends both The Representation of the People Acts of 1950 and 1951. One of its main provisions creates a legal framework to link electoral roll data with Aadhaar, the unique identification number. It is meant to strike out bogus voters, dead voters, foreigners who are wrongfully included as voters and also those who are enrolled in more than one constituency.'"
+},
+{
+ "Question": "What role does the Printing Section play in the Legislative Department?",
+ "Answer": "According to Section 36 of the document, the Printing Sections (Printing I and II) handle 'the processing of legislation for printing at various stages' including 'editing of manuscripts of the Bills (including preparation of contents and annexures), Ordinances, Regulations, Adaptation Orders, Orders issued under the Constitution of India, Delimitation Orders and other statutory instruments before sending them to Press.' During January-December 2021, they edited manuscripts and checked proofs for 89 Bills, 49 Gazettes, 10 Ordinances, and prepared 49 A-4 Acts."
+},
+ {
+ "Question": "How many Official Language versions of the Constitution of India have been published?",
+ "Answer": "According to Section 41(3) of the document, the Constitution of India has been published in Hindi (the Official Language of the Union) and 16 other regional languages: 'Assamese, Bengali, Gujarati, Kannada, Malayalam, Marathi, Manipuri, Oriya, Punjabi, Sanskrit, Tamil, Telugu, Urdu, Sindhi, Nepali and Konkani.'"
+ }
+]
diff --git a/examples/DocQA/data/eval/README.md b/examples/DocQA/data/eval/README.md
new file mode 100644
index 000000000..ba042b9cd
--- /dev/null
+++ b/examples/DocQA/data/eval/README.md
@@ -0,0 +1,98 @@
+# RAG System Evaluation
+
+This directory contains tools for evaluating the Retrieval-Augmented Generation (RAG) system using RAGAS metrics.
+
+## Setup
+
+1. Create your environment file:
+
+```bash
+cp .env.template .env
+```
+
+2. Configure the environment variables in `.env`:
+
+```env
+# Server Configuration
+HOST=localhost # Your server host
+PORT=5000 # Your server port
+CHROMA_PORT=8000 # Chroma DB port
+
+# Model and Memory Configuration
+MODEL_NAME=meta-llama/Llama-3.2-3B-Instruct # Model to use
+MEMORY_BANK_ID=eval_bank # Memory bank identifier
+
+# File Paths
+DOCS_DIR=../output # Directory containing your documents
+```
+
+## Running the Evaluation
+
+1. Make sure your server is running and accessible at the configured host and port.
+
+2. Run the evaluation script:
+
+```bash
+python eval.py
+```
+
+The script will:
+
+- Set up a memory bank for evaluation
+- Load your documents
+- Generate responses for test questions
+- Evaluate the responses using various RAGAS metrics:
+ - Context Precision
+ - Context Recall
+ - Faithfulness
+ - Answer Relevancy
+ - Factual Correctness
+ - Semantic Similarity
+
+Results will be saved to `evaluation_results.csv`.
+
+## Analyzing Results
+
+For detailed analysis of your evaluation results, you can use the Jupyter notebook:
+
+```bash
+jupyter notebook explain-eval.ipynb
+```
+
+The notebook provides:
+
+- Visualization of evaluation metrics
+- Detailed breakdown of each metric
+- Analysis of system performance
+- Insights for improvement
+
+## Metrics Explanation
+
+The evaluation uses the following RAGAS metrics:
+
+1. **Context Precision**: Measures how much of the retrieved context is actually relevant
+2. **Context Recall**: Measures if all relevant information was retrieved
+3. **Faithfulness**: Measures if the answer is faithful to the provided context
+4. **Answer Relevancy**: Measures if the answer is relevant to the question
+5. **Factual Correctness**: Measures the factual accuracy of the answer
+6. **Semantic Similarity**: Measures semantic closeness between answer and reference
+
+## Troubleshooting
+
+If you encounter issues:
+
+1. Verify your server is running and accessible
+2. Check the environment variables in `.env`
+3. Ensure your documents are in the correct directory
+4. Check the logs for detailed error messages
+
+## Requirements
+
+- Python 3.10+
+- Jupyter Notebook (for analysis)
+- Required Python packages (install via `pip`):
+ - ragas
+ - datasets
+ - pandas
+ - numpy
+ - matplotlib (for visualization)
diff --git a/examples/DocQA/data/eval/eval.py b/examples/DocQA/data/eval/eval.py
new file mode 100644
index 000000000..4a193ca07
--- /dev/null
+++ b/examples/DocQA/data/eval/eval.py
@@ -0,0 +1,321 @@
+import asyncio
+import json
+import logging
+import os
+import uuid
+from dataclasses import dataclass
+from pathlib import Path
+from typing import List, Optional, Tuple, Dict, Any
+
+import chromadb
+import fire
+import requests
+from datasets import Dataset
+from dotenv import load_dotenv
+from llama_stack_client import LlamaStackClient
+from llama_stack_client.lib.agents.agent import Agent
+from llama_stack_client.types.agent_create_params import AgentConfig
+from llama_stack_client.types.memory_insert_params import Document
+from ragas import evaluate
+from ragas.metrics import (
+ AnswerRelevancy,
+ ContextPrecision,
+ ContextRecall,
+ FactualCorrectness,
+ Faithfulness,
+ SemanticSimilarity,
+)
+from tqdm import tqdm
+
+# Configure logging
+logging.basicConfig(
+ level=logging.INFO,
+ format='%(asctime)s - %(levelname)s - %(message)s'
+)
+logger = logging.getLogger(__name__)
+
+
+@dataclass
+class Config:
+ """Configuration for the evaluation script."""
+ host: str
+ port: int
+ chroma_port: int
+ model_name: str
+ memory_bank_id: str
+ docs_dir: Path
+
+ @classmethod
+ def from_env(cls) -> 'Config':
+ """Create configuration from environment variables."""
+ load_dotenv()
+ return cls(
+ host=os.getenv("HOST", "localhost"),
+ port=int(os.getenv("PORT", 5000)),
+ chroma_port=int(os.getenv("CHROMA_PORT", 8000)),
+ model_name=os.getenv(
+ "MODEL_NAME", "meta-llama/Llama-3.2-3B-Instruct"),
+ memory_bank_id=os.getenv("MEMORY_BANK_ID", "test_bank_236"),
+ docs_dir=Path(os.getenv("DOCS_DIR", "../output")).resolve(),
+ )
+
+
+class MemoryBankManager:
+ """Manages memory bank operations."""
+
+ def __init__(self, client: LlamaStackClient, config: Config):
+ self.client = client
+ self.config = config
+
+ async def setup(self) -> None:
+ """Set up the memory bank if it doesn't exist."""
+ try:
+ providers = self.client.providers.list()
+ provider_id = providers["memory"][0].provider_id
+ memory_banks = self.client.memory_banks.list()
+
+ if any(bank.identifier == self.config.memory_bank_id for bank in memory_banks):
+ logger.info(
+ f"Memory bank '{self.config.memory_bank_id}' exists.")
+ return
+
+ logger.info(
+ f"Creating memory bank '{self.config.memory_bank_id}'...")
+ self.client.memory_banks.register(
+ memory_bank_id=self.config.memory_bank_id,
+ provider_id=provider_id,
+ )
+ await self._load_documents()
+ logger.info("Memory bank registered successfully.")
+
+ except Exception as e:
+ logger.error(f"Failed to setup memory bank: {str(e)}")
+ raise
+
+ async def _load_documents(self) -> None:
+ """Load documents from the specified directory into memory bank."""
+ try:
+ documents = []
+ for file_path in self.config.docs_dir.glob("*.{txt,md}"):
+ document = self._create_document(file_path)
+ if document:
+ documents.append(document)
+
+ if documents:
+ self.client.memory.insert(
+ bank_id=self.config.memory_bank_id,
+ documents=documents,
+ )
+ logger.info(
+ f"Loaded {len(documents)} documents from {self.config.docs_dir}")
+
+ except Exception as e:
+ logger.error(f"Failed to load documents: {str(e)}")
+ raise
+
+ def _create_document(self, file_path: Path) -> Optional[Document]:
+ """Create a Document object from a file."""
+ try:
+ content = file_path.read_text(encoding="utf-8")
+ return Document(
+ document_id=file_path.name,
+ content=content,
+ mime_type="text/plain",
+ metadata={"filename": file_path.name},
+ )
+ except Exception as e:
+ logger.error(
+ f"Failed to create document from {file_path}: {str(e)}")
+ return None
+
+ def query(self, query: str) -> Optional[Dict[str, Any]]:
+ """Query memory bank for relevant context."""
+ try:
+ response = self.client.memory.query(
+ bank_id=self.config.memory_bank_id,
+ query=[query],
+ )
+
+ if response.chunks and response.scores:
+ return {
+ "documents": [chunk.content for chunk in response.chunks],
+ "metadatas": [{"content": chunk.content} for chunk in response.chunks],
+ "distances": response.scores
+ }
+ return None
+
+ except Exception as e:
+ logger.error(f"Failed to query memory: {str(e)}")
+ return None
+
+
+class ResponseGenerator:
+ """Handles generation of responses using the agent."""
+
+ def __init__(self, agent: Agent, memory_manager: MemoryBankManager):
+ self.agent = agent
+ self.memory_manager = memory_manager
+
+ async def get_response(self, query: str, session_id: str) -> Tuple[str, List[str]]:
+ """Generate a response for the given query using context from memory."""
+ try:
+ context, contexts = self._get_context(query)
+ messages = [
+ {"role": "user", "content": f"Context: {context}\n\nQuestion: {query}"}]
+
+ response = self.agent.create_turn(
+ messages=messages, session_id=session_id)
+ return self._process_response(response), contexts
+
+ except Exception as e:
+ logger.error(f"Failed to generate response: {str(e)}")
+ return "Error generating response.", []
+
+ def _get_context(self, query: str) -> Tuple[str, List[str]]:
+ """Get context for the query from memory."""
+ results = self.memory_manager.query(query)
+ if results and results["metadatas"]:
+ contexts = [metadata["content"]
+ for metadata in results["metadatas"]]
+ context = "\n".join(f"Content:\n{ctx}" for ctx in contexts)
+ return context, contexts
+ return "No relevant context found.", []
+
+ def _process_response(self, response) -> str:
+ """Process the response from the agent."""
+ full_response = ""
+ for chunk in response:
+ if hasattr(chunk, "event"):
+ if chunk.event.payload.event_type == "turn_complete":
+ return chunk.event.payload.turn.output_message.content
+ elif hasattr(chunk.event.payload, "delta"):
+ full_response += chunk.event.payload.delta.content or ""
+ return full_response or "No response generated."
+
+
+class Evaluator:
+ """Handles evaluation of the question-answering system."""
+
+ def __init__(self, config: Config):
+ self.config = config
+
+ async def run_evaluation(self) -> None:
+ """Run the evaluation process."""
+ try:
+ client = self._setup_client()
+ memory_manager = MemoryBankManager(client, self.config)
+ await memory_manager.setup()
+
+ agent = self._setup_agent(client)
+ response_generator = ResponseGenerator(agent, memory_manager)
+
+ qa_data = self._load_qa_data()
+ results = await self._process_questions(response_generator, qa_data)
+ self._evaluate_and_save_results(results)
+
+ except Exception as e:
+ logger.error(f"Evaluation failed: {str(e)}")
+ raise
+
+ def _setup_client(self) -> LlamaStackClient:
+ """Set up the LlamaStack client."""
+ return LlamaStackClient(base_url=f"http://{self.config.host}:{self.config.port}")
+
+ def _setup_agent(self, client: LlamaStackClient) -> Agent:
+ """Set up the agent with configuration."""
+ agent_config = AgentConfig(
+ model=self.config.model_name,
+ instructions="You are a helpful assistant that can answer questions based on provided documents.",
+ sampling_params={"strategy": "greedy",
+ "temperature": 1.0, "top_p": 0.9},
+ tools=[{
+ "type": "memory",
+ "memory_bank_configs": [{"bank_id": self.config.memory_bank_id, "type": "vector"}],
+ }],
+ tool_choice="auto",
+ tool_prompt_format="json",
+ enable_session_persistence=True,
+ )
+ return Agent(client, agent_config)
+
+ def _load_qa_data(self) -> List[Dict[str, str]]:
+ """Load QA evaluation data."""
+ qa_file_path = Path(__file__).parent / "QA_eval.json"
+ with qa_file_path.open('r') as f:
+ return json.load(f)[:10]
+
+ async def _process_questions(
+ self,
+ response_generator: ResponseGenerator,
+ qa_data: List[Dict[str, str]]
+ ) -> Dict[str, List]:
+ """Process all questions and collect results."""
+ results = {
+ "questions": [],
+ "generated_answers": [],
+ "retrieved_contexts": [],
+ "ground_truths": []
+ }
+
+ session_id = f"session-{uuid.uuid4()}"
+ for qa in tqdm(qa_data, desc="Generating responses"):
+ try:
+ question = qa["Question"]
+ ground_truth = qa["Answer"]
+
+ answer, contexts = await response_generator.get_response(question, session_id)
+
+ results["questions"].append(question)
+ results["generated_answers"].append(answer)
+ results["retrieved_contexts"].append(
+ [str(ctx) for ctx in contexts])
+ results["ground_truths"].append(ground_truth)
+
+ except Exception as e:
+ logger.error(f"Failed to process question: {str(e)}")
+ continue
+
+ return results
+
+ def _evaluate_and_save_results(self, results: Dict[str, List]) -> None:
+ """Evaluate and save the results."""
+ eval_data = Dataset.from_dict({
+ "user_input": results["questions"],
+ "response": results["generated_answers"],
+ "retrieved_contexts": results["retrieved_contexts"],
+ "reference": results["ground_truths"],
+ })
+
+ metrics = [
+ ContextPrecision(),
+ ContextRecall(),
+ Faithfulness(),
+ AnswerRelevancy(),
+ FactualCorrectness(),
+ SemanticSimilarity(),
+ ]
+
+ evaluation_result = evaluate(eval_data, metrics=metrics)
+ df = evaluation_result.to_pandas()
+ df.to_csv("evaluation_results.csv", index=False)
+ logger.info("\nEvaluation Results:")
+ logger.info("\n" + str(df))
+
+
+async def run_main(docs_dir: str = None) -> None:
+ """Main entry point for the evaluation script."""
+ config = Config.from_env()
+ if docs_dir:
+ config.docs_dir = Path(docs_dir).resolve()
+
+ evaluator = Evaluator(config)
+ await evaluator.run_evaluation()
+
+
+def main() -> None:
+ """CLI entry point."""
+ asyncio.run(run_main())
+
+
+if __name__ == "__main__":
+ fire.Fire(main)
diff --git a/examples/DocQA/data/eval/evaluation_results.csv b/examples/DocQA/data/eval/evaluation_results.csv
new file mode 100644
index 000000000..09b235f37
--- /dev/null
+++ b/examples/DocQA/data/eval/evaluation_results.csv
@@ -0,0 +1,29 @@
+user_input,retrieved_contexts,response,reference,context_precision,context_recall,faithfulness,answer_relevancy,factual_correctness,semantic_similarity
+What is the policy regarding smoking in City offices?,"[' productive workplace which is free from inappropriate workplace behavior.\n\n## Smoke-Free Workplace\n\nSmoking is not permitted in City offices, or within n 20 feet of entrances, exits, or operable windows of public buildings.\n\n## Drug-Free Workplace\n\nYou may not manufacture, distribute, dispense, possess, use or be under the influence of alcohol or illegal drugs in workplace. This prohibition includes prescription drugs used improperly (e.g., those not prescribed for the user). Any violation of this policy may be grounds', '45 |\n| Policy Regarding the Treatment of Co-Workers and Members of the Public ...................46 |\n| Smoke-Free Workplace .....................................................................................................46 |\n| Drug-Free Workplace ........................................................................................................46 Disciplinary Action against Striking Employees ...............................................................47 |\n| Political Activity ................................................................................................................47 |\n\n| If You Suspect Improper or Criminal Activity on the Job .................................................47 |\n|---------------------------------------------------------------------------------------------------------------------------------------------|\n| Use of City and County Property for Business Purposes', ' City resources or divert employees from their assigned duties.\n\nCity employees are prohibited from using their official positions to influence elections, and from using City funds or resources for political or r election activities. Further, City employees may not participate in political activities of any kind while in uniform (i.e., part or all of a uniform they are required or authorized to wear when engaged in official duties).\n\nViolation of these rules may result in considerable civil and criminal penalties, as well as discipline, up to and including']",No response generated.,"Smoking is not permitted in City offices, or within 20 feet of entrances, exits, or operable windows of public buildings. (Source: Page 46, 'Smoke-Free Workplace' section)",0.99999999995,0.5,0.0,0.0,0.0,0.7310965383185614
+How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules?,"[' Accrual of Paid Sick Leave\n\nSick leave with pay is a privilege under the Civil Service Rules, Charter and City Ordinance.\n\nMost full time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. Unused sick leave accrued under the Civil Service Rules may be accumulated from year to year up to a maximum of 130 8-hour working days.\n\nSome employees may be entitled to accrue sick leave under Chapter 12W of the Administrative', ' must complete the appropriate form and comply with the specific requirements for that type of leave. All requests for leave of more than five working days must be made in writing on the appropriate form. Please see your departmental personnel officer for more information .\n\n## Sick Leave\n\nPlease refer to your collective bargaining agreement and the Civil Service Rules or contact your departmental personnel officer for more information regarding sick leave accrual, usage, and notice and verification requirements.\n\n## Accrual of Paid Sick Leave\n\nSick', ' leave under Chapter 12W of the Administrative Code. Please contact your departmental personnel officer for more information.\n\n## Sick Leave without Pay\n\nYou may be eligible to take sick leave without pay. Please refer to the Civil Service Rules and any applicable collective bargaining agreement for more information.\n\n## Use of Sick Leave\n\nYou may not use sick leave with pay accrued under the Civil Service Rules during your first 6 months of employment with the City.\n\nYou may not use sick leave for reasons not set']",No response generated.,"Most full-time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. (Source: Page 32, 'Accrual of Paid Sick Leave' section)",0.9999999999,0.5,0.0,0.0,0.0,0.7089057204017655
+What are the three categories of employees eligible for health coverage?,"[' health coverage:\n\n- (1) All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours;\n- (2) All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours; and\n- (3) All other employees of the City including temporary y exempt or ""as needed"" employees who have worked more than 1040 hours in any consecutive ', '02.\n\n## EMPLOYEE BENEFITS\n\nThe City provides eligible employees and their eligible dependents the opportunity to enroll in medical, dental, vision and flexible spending account benefits, administered by the Health Service System (""HSS"").\n\nPlease note that the information in this section is subject to change. You should consult with HSS if you have any questions at (415) 554-1750.\n\n## Eligibility\n\nThe following employees are eligible for health coverage:\n\n- (1) All permanent employees', ' of the employee organization, is available at the discretion of the department head.\n\nWhile the employee is on leave, the employee organization is responsible for paying the employee\'s salary.\n\nBefore the leave begins, the employee may choose to either continue or waive access to health coverage through the City for the duration of the approved leave. If the employee wishes to continue his or her health coverage, premium contributions for the employee and any covered dependents must be paid directly to the Health Services System (""HSS"").']",No response generated.,"The following employees are eligible:
+
+All permanent employees working at least 20 hours per week
+
+All regularly scheduled provisional employees working at least 20 hours per week
+
+All other employees (including temporary exempt or 'as needed') who have worked more than 1040 hours in any consecutive 12-month period and work at least 20 hours per week (Source: Page 25, 'Eligibility' section)",0.99999999995,1.0,0.0,0.0,0.0,0.6871705187744059
+How long must an employee wait before using vacation time after starting employment?,"[', you will be awarded a vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year and will be eligible to use accrued vacation time. For the purpose of computing vacation, most employees may be credited with no more than 2080 hours of service in a 12month period.\n\nAn additional vacation entitlement will be awarded after five years of continuous service, usually 40 hours for full-time employees. After fifteen years of service, full-time employees will', 'ing officer and the provisions of the applicable collective bargaining agreement. Contact your departmental personnel officer or payroll representative for more information.\n\n## Vacation\n\nThe City provides annual vacations for employees who work a regular schedule and who have completed one year or more of continuous service. Certain temporary exempt employees may also be eligible for vacation benefits. You are not eligible to use vacation in the first year of continuous service; however, at the end of one year of continuous service, you will be awarded a vacation allowance at the', "" department's procedures for details.\n\nWhen a holiday falls on a regular working day during your vacation, the holiday is not counted as a vacation day. If you resign or are separated after one or more years of continuous service and have not taken all of your vacation, you will be paid for the accumulated unused vacation.\n\nRequests to take vacation must be made and approved d in advance, in accordance with your department's procedures.\n\n## LEAVES OF ABSENCE\n\nLeaves of absence are governed by the""]",No response generated.,"Employees are not eligible to use vacation in the first year of continuous service. After one year of continuous service, they are awarded vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year. (Source: Page 30, 'Vacation' section)",0.99999999995,0.6666666666666666,0.0,0.0,0.0,0.710133331048373
+What must an employee do if they're summoned for jury duty?,"[' you would return to the workplace to work the remaining two hours each day and continue to take Friday off.\n\nYou are not entitled to a per diem pay from the City or County for which Jury Duty was served, as the City and County of San Francisco already provides regular compensation and benefits to you while performing jury service. You must notify the jury staff that you are a government employee when reporting for jury service\n\n## Witness Duty\n\nIf you are summoned as a witness on behalf of the City and', ' 10 days of unpaid leave during a period of his or her leave from deployment. Please refer to the Civil Service Rules for details or consult your departmental personnel officer for more information.\n\n## Jury Duty Leave\n\nYou must notify your supervisor as soon as you receive a jury summons. If you are required to report for jury duty during your working hours, you will be excused from work on the work day you perform jury service, provided you give prior notification to your supervisor. If you report', ' give prior notification to your supervisor. If you report for jury duty and are not selected as a juror, or if the court dismisses the proceedings early for the day, you must return to work as soon as possible.\n\n## Work Schedule While on Jury Duty\n\nAlternative Work Schedule. If you have an alternative work schedule and perform jury service for an extended period, your work schedule will revert to a regular Monday through Friday work schedule for compensation purposes for the duration of the jury service.\n\nSwing and']",No response generated.,"An employee must notify their supervisor as soon as they receive a jury summons. If required to report during working hours, they will be excused from work on the day they perform jury service, provided they give prior notification. If not selected or dismissed early, they must return to work as soon as possible. (Source: Page 37, 'Jury Duty Leave' section)",0.5833333333041666,0.75,0.0,0.0,0.0,0.7250633971841919
+What happens if an employee is absent without authorization for more than five consecutive working days?,"[' work and the number of hours worked in every work day.\n\nAll planned absences must be requested and approved d in advance. If illness or some other emergency causes an unplanned or unforeseeable absence, you must notify your department as soon as possible on the first day of absence, and keep the department advised daily during the absence. In the case of an extended unforeseeable absence, you may be asked to complete forms and submit medical certifications as appropriate during your leave. Improper use of sick', 'ation\n\nIf you are absent from your job for any period of time without proper authorization, you may be subject to discipline. If you are absent from your r job without proper authorization for more than five consecutive working days, or if you fail to return from an approved leave, your absence will be deemed an ""automatic resignation."" If you receive a notice of automatic resignation and wish to appeal the determination to the Civil Service Commission, you will have fifteen days from the date on which the notice was mailed to', ' period of incarceration .\n\nPlease see your departmental personnel officer if you have any questions regarding appropriate uses of sick leave.\n\n## Notice and Verification Requirements\n\nIt is your responsibility to notify your supervisor r as soon as possible whenever you are unable to report for work due to illness. You must t keep your supervisor informed throughout your absence and notify your supervisor of your expected date of return to work.\n\nIf you are absent from your job for more than five consecutive working days, you must submit to your supervisor a completed']",No response generated.,"If an employee is absent from their job without proper authorization for more than five consecutive working days, or fails to return from an approved leave, their absence will be deemed an 'automatic resignation.' (Source: Page 19, 'Automatic Resignation' section)",0.49999999995,1.0,0.0,0.0,0.0,0.7395137950936732
+How long is the normal probationary period for permanent civil service positions?,"["" and most important phase of the selection process. This period is used to evaluate your performance and suitability for the position. The duration of the probationary period is governed by the collective bargaining agreement. Absences from work will extend your probationary period. For infoformation about the length of your probationary period, consult your departmental personnel officer or collective bargaining agreement.\n\nThe department's appointing officer may release an employee at any time during the probationary period. At the conclusion of the probationary period,"", ' of eligibles to a permanent position. Permanent empmployees who have successfully completed the probationary period may only be removed for cause.\n\n## Exempt\n\nPersons appointed to temporary or permanent positions exempted from civil service status in accordance with the City Charter. Exempt t appointees serve at the pleasure of the appointing officer.\n\n## Provisional\n\nProvisional appointments are made when an eligible list for the classification is not available. The just cause rights of provisional employees are described in the', ' the class from m which they resigned within four years from the date of resignation. Former members of the uniformed ranks of the Police and Fire departments may be reappointed within two years of the date of resignation. Former employees may request reappointment to a vacancy in any class in which the employee has completed the probationary period. The receiving department, at i its discretion, may approve a request for reappointment.\n\n## Reinstatement\n\nAn employee may submit a written request to return to a vacant']",No response generated.,"The document states that all appointments to permanent civil service positions require a probationary period, but the duration is governed by the collective bargaining agreement. Absences from work will extend the probationary period. (Source: Page 14, 'Probationary Period' section)",0.99999999995,0.6666666666666666,0.0,0.0,0.0,0.7124925328695783
+What are employees required to do in case of a catastrophic event while off duty?,"[' whatever role you are directed to perform by a superior or by law.\n\nAll Disaster Services Workers will be issued a citywide identification badge. You must have your badge with you at all times.\n\nCatastrophic Event While on Duty: Should a catastrophic event occur while you are on duty, report immediately to your supervisor or designated areas for assignment.\n\nCatastrophic Event While off Duty: Should a catastrophic event occur while you are off duty, you should ensure the safety of your family and follow your', ' less.\n\n## Disaster Service Workers - Your Responsibilities in Case of Emergency\n\nAll City employees are designated Disaster Service Workers under state and local law. If the Mayor or an authorized City official proclaims a local emergency due to actual or threatened disaster such as earthquake, fire, riot, etc., City employees, as Disaster Service Workers, may be required to provide services during the emergency and subsequent period of assessment and recovery.\n\nSimply put, being a Disaster Service Worker means that any time a catastrophic event-', "" healthful work environment.\n\nSafety is every City employee's responsibility. All employees are required to remain alert and to correct hazardous conditions and unsafe acts-if it is safe to do so-and to report unsafe conditions to their supervisors.\n\n## On-the-Job Injury and Workers' Compensation\n\nAll City employees are covered by State Workers' Compensation laws. If you are injured at work or because of your work, you must report the injury or illness to your immediate supervisor as soon as possible, and no later than the""]",No response generated.,"Employees should ensure the safety of their family and follow their department's instructions. If phone lines are down, they are required to listen to the radio for any reporting instructions. (Source: Page 51, 'Catastrophic Event While off Duty' section)",0.99999999995,0.5,0.0,0.0,0.0,0.7465800852696091
+What is the city's policy on accepting gifts from subordinates?,"[' a copy of your department\'s ""Statement of Incompatible Activities,"" please see your departmental personnel officer or go to the Ethics Commission website at www.sfgov.org/site/ethics.\n\n## Gifts\n\nYou may not accept any gift that is intended to inflfluence you in the performance of your job.\n\nYou may not solicit or accept any gift from any person or entity who has a contract with your department or who has attempted to influence you in a governmental decision during the past 12 months', ' a governmental decision during the past 12 months.\n\nYou may not solicit or accept any gifts from any subordinate, or any candidate or applicant for a position as an employee or subordinate to you .\n\nIf you are required to file a Statement of Economic Interests (""SEI"") financial disclosure, you cannot accept gifts worth more than a certain amount in a calendar year from any source that you must report on your SEI. That amount is $420.00 for calendar year 2011; please', ' recipient to believe that you are speaking in an official capacity when you are not.\n- You may not make, participate in, or attempt to inflfluence a governmental decision affecting a person or entity with whom you are discussing or negotiating an agreement concerning future employment.\n- You may not accept any compensation, reward, or gift ft from any source except the City for any service, advice, assistance or other matter related to your City job.\n- You may not solicit or accept anything of value in']",No response generated.,"Employees may not solicit or accept any gifts from any subordinate, or any candidate or applicant for a position as an employee or subordinate to them. (Source: Page 49, 'Gifts' section)",0.9999999999666667,0.5,0.0,0.0,0.0,0.7311572952124511
+What documents must new employees present at the time of hire?,"['\n\nPrior to employment in certain positions or classififications, departments may require a background review of criminal history, motor vehicle (driving) record, personnel history and employment records. The requirement for a background review will be published on the examination announcement.\n\n## Medical Examination\n\nDepending on the classification or position in which you are to be employed, you may be required to pass a medical examination, including drug testing, as a condition of employment. Most medical examinations are conducted by the Deparartment of Public', ' these documents may result in loss of eligibility. Acceptable verification documents are listed in the information pamphlet entitled ""Federal Immigration and Naturalization Service Requirements,"" available at the Department of Human Resources\' (""DHR"") Employment Information Center, located on the 4 th floor at 1 South Van Ness Avenue.\n\nAny applicant or employee seeking to have the City p provide documentation to the Department of Homeland Security (including the U.S. Citizenship and Immigration Services) about possible or actual employment with the City must obtain', 'ingerprinting\n\nAll employees must be fingerprinted. Fingerprints are electronically transmitted to the California Department of Justice to obtain conviction records.\n\n## REQUIREMENTS AT THE TIME OF HIRE\n\n## Social Security Number\n\nYou must have a Social Security number to work for the City.\n\n## Authorization to Work\n\nYou must present documents to verify identity and authorization to work in the United States as required by the Immigration Reform Control Act of 1986. Failure to provide these documents may result in loss of eligibility. Accept']",No response generated.,"New employees must present:
+
+Social Security number
+
+Documents to verify identity and authorization to work in the United States
+
+Take the Oath of Office
+
+Sign acknowledgment of no-strike provision
+
+Complete tax forms (W-4)
+
+Complete Warrant Recipient Form (Source: Pages 11-12, 'Requirements at the Time of Hire' section)",0.3333333333,0.3333333333333333,0.0,0.0,0.0,0.7086797649178207
diff --git a/examples/DocQA/data/eval/explain-eval.ipynb b/examples/DocQA/data/eval/explain-eval.ipynb
new file mode 100644
index 000000000..8d90fac04
--- /dev/null
+++ b/examples/DocQA/data/eval/explain-eval.ipynb
@@ -0,0 +1,745 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "1",
+ "metadata": {},
+ "source": [
+ "### **RAGAS Evaluation Results Analysis**\n",
+ "\n",
+ "Let's anaylze our RAG based on these four metrics, Context Precision, Context Recall, Faithfullness, and Answer Relevancy."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "\n",
+ "sns.set_style('whitegrid')\n",
+ "%matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6",
+ "metadata": {},
+ "source": [
+ "#### Understanding the Metrics\n",
+ "\n",
+ "**Context Precision**\n",
+ "\n",
+ "- **Definition**: Measures the proportion of relevant chunks in the retrieved contexts.\n",
+ "- **Interpretation**: A higher value indicates that most of the retrieved contexts are relevant to the user query.\n",
+ "\n",
+ "**Context Recall**\n",
+ "\n",
+ "- **Definition**: Measures how many of the relevant documents were successfully retrieved.\n",
+ "- **Interpretation**: A higher value means fewer relevant documents were left out.\n",
+ "\n",
+ "**Faithfulness**\n",
+ "\n",
+ "- **Definition**: Measures the factual consistency of the generated answer against the given context.\n",
+ "- **Interpretation**: A higher value indicates that the answer is well-supported by the retrieved contexts.\n",
+ "\n",
+ "**Answer Relevancy**\n",
+ "\n",
+ "- **Definition**: Assesses how pertinent the generated answer is to the given prompt.\n",
+ "- **Interpretation**: Higher scores indicate that the answer directly addresses the user's question."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8",
+ "metadata": {},
+ "source": [
+ "#### Data Preparation\n",
+ "\n",
+ "Lets visualize our dataset before we dive into the metrics."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
user_input
\n",
+ "
retrieved_contexts
\n",
+ "
response
\n",
+ "
reference
\n",
+ "
context_precision
\n",
+ "
context_recall
\n",
+ "
faithfulness
\n",
+ "
answer_relevancy
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
0
\n",
+ "
What is the policy regarding smoking in City o...
\n",
+ "
['## Smoke-Free Workplace\\n\\nSmoking is not pe...
\n",
+ "
According to the document, smoking is not perm...
\n",
+ "
Smoking is not permitted in City offices, or w...
\n",
+ "
1.000000
\n",
+ "
1.000000
\n",
+ "
1.0
\n",
+ "
0.968476
\n",
+ "
\n",
+ "
\n",
+ "
1
\n",
+ "
How many days of paid sick leave do most full-...
\n",
+ "
['Most full time employees earn 13 8-hour work...
\n",
+ "
Most full-time employees earn 13 8-hour workin...
\n",
+ "
Most full-time employees earn 13 8-hour workin...
\n",
+ "
1.000000
\n",
+ "
0.500000
\n",
+ "
1.0
\n",
+ "
0.986973
\n",
+ "
\n",
+ "
\n",
+ "
2
\n",
+ "
What are the three categories of employees eli...
\n",
+ "
['The following employees are eligible for hea...
\n",
+ "
The three categories of employees eligible for...
\n",
+ "
The following employees are eligible:\\n\\nAll p...
\n",
+ "
0.700000
\n",
+ "
1.000000
\n",
+ "
0.8
\n",
+ "
0.981254
\n",
+ "
\n",
+ "
\n",
+ "
3
\n",
+ "
How long must an employee wait before using va...
\n",
+ "
['An additional vacation entitlement will be a...
\n",
+ "
An employee must wait at least one year of con...
\n",
+ "
Employees are not eligible to use vacation in ...
\n",
+ "
0.416667
\n",
+ "
0.666667
\n",
+ "
1.0
\n",
+ "
0.979251
\n",
+ "
\n",
+ "
\n",
+ "
4
\n",
+ "
What must an employee do if they're summoned f...
\n",
+ "
['You must notify your supervisor as soon as y...
\n",
+ "
An employee must notify their supervisor as so...
\n",
+ "
An employee must notify their supervisor as so...
\n",
+ "
0.916667
\n",
+ "
0.750000
\n",
+ "
1.0
\n",
+ "
0.965414
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " user_input \\\n",
+ "0 What is the policy regarding smoking in City o... \n",
+ "1 How many days of paid sick leave do most full-... \n",
+ "2 What are the three categories of employees eli... \n",
+ "3 How long must an employee wait before using va... \n",
+ "4 What must an employee do if they're summoned f... \n",
+ "\n",
+ " retrieved_contexts \\\n",
+ "0 ['## Smoke-Free Workplace\\n\\nSmoking is not pe... \n",
+ "1 ['Most full time employees earn 13 8-hour work... \n",
+ "2 ['The following employees are eligible for hea... \n",
+ "3 ['An additional vacation entitlement will be a... \n",
+ "4 ['You must notify your supervisor as soon as y... \n",
+ "\n",
+ " response \\\n",
+ "0 According to the document, smoking is not perm... \n",
+ "1 Most full-time employees earn 13 8-hour workin... \n",
+ "2 The three categories of employees eligible for... \n",
+ "3 An employee must wait at least one year of con... \n",
+ "4 An employee must notify their supervisor as so... \n",
+ "\n",
+ " reference context_precision \\\n",
+ "0 Smoking is not permitted in City offices, or w... 1.000000 \n",
+ "1 Most full-time employees earn 13 8-hour workin... 1.000000 \n",
+ "2 The following employees are eligible:\\n\\nAll p... 0.700000 \n",
+ "3 Employees are not eligible to use vacation in ... 0.416667 \n",
+ "4 An employee must notify their supervisor as so... 0.916667 \n",
+ "\n",
+ " context_recall faithfulness answer_relevancy \n",
+ "0 1.000000 1.0 0.968476 \n",
+ "1 0.500000 1.0 0.986973 \n",
+ "2 1.000000 0.8 0.981254 \n",
+ "3 0.666667 1.0 0.979251 \n",
+ "4 0.750000 1.0 0.965414 "
+ ]
+ },
+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pd.reset_option('display.max_colwidth')\n",
+ "pd.reset_option('display.max_rows')\n",
+ "\n",
+ "data = pd.read_csv('evaluation_results.csv')\n",
+ "data.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "667df35e-e61e-41a4-bb1a-b59ce9656f78",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
user_input
\n",
+ "
response
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
0
\n",
+ "
What is the policy regarding smoking in City offices?
\n",
+ "
According to the document, smoking is not permitted in City offices, or within n 20 feet of entrances, exits, or operable windows of public buildings.
\n",
+ "
\n",
+ "
\n",
+ "
1
\n",
+ "
How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules?
\n",
+ "
Most full-time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules.
\n",
+ "
\n",
+ "
\n",
+ "
2
\n",
+ "
What are the three categories of employees eligible for health coverage?
\n",
+ "
The three categories of employees eligible for health coverage are:\\n\\n1. All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n2. All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n3. All other employees of the City, including temporary, exempt, or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12-month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours.
\n",
+ "
\n",
+ "
\n",
+ "
3
\n",
+ "
How long must an employee wait before using vacation time after starting employment?
\n",
+ "
An employee must wait at least one year of continuous service before using vacation time. At the end of the first year, the employee will be awarded a vacation allowance at the rate of 0.0385 of an hour for each hour of paid service in the preceding year, and will be eligible to use accrued vacation time.
\n",
+ "
\n",
+ "
\n",
+ "
4
\n",
+ "
What must an employee do if they're summoned for jury duty?
\n",
+ "
An employee must notify their supervisor as soon as they receive a jury summons. If they are required to report for jury duty during their working hours, they will be excused from work on the work day they perform jury service, provided they give prior notification to their supervisor.
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " user_input \\\n",
+ "0 What is the policy regarding smoking in City offices? \n",
+ "1 How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules? \n",
+ "2 What are the three categories of employees eligible for health coverage? \n",
+ "3 How long must an employee wait before using vacation time after starting employment? \n",
+ "4 What must an employee do if they're summoned for jury duty? \n",
+ "\n",
+ " response \n",
+ "0 According to the document, smoking is not permitted in City offices, or within n 20 feet of entrances, exits, or operable windows of public buildings. \n",
+ "1 Most full-time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. \n",
+ "2 The three categories of employees eligible for health coverage are:\\n\\n1. All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n2. All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n3. All other employees of the City, including temporary, exempt, or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12-month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours. \n",
+ "3 An employee must wait at least one year of continuous service before using vacation time. At the end of the first year, the employee will be awarded a vacation allowance at the rate of 0.0385 of an hour for each hour of paid service in the preceding year, and will be eligible to use accrued vacation time. \n",
+ "4 An employee must notify their supervisor as soon as they receive a jury summons. If they are required to report for jury duty during their working hours, they will be excused from work on the work day they perform jury service, provided they give prior notification to their supervisor. "
+ ]
+ },
+ "execution_count": 40,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pd.set_option('display.max_colwidth', None)\n",
+ "pd.set_option('display.max_rows', None)\n",
+ "\n",
+ "data[['user_input', 'response']].head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "df53125e-70e1-401c-85b9-10e3c668ba08",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
retrieved_contexts
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
0
\n",
+ "
['## Smoke-Free Workplace\\n\\nSmoking is not permitted in City offices, or within n 20 feet of entrances, exits, or operable windows of public buildings.\\n\\n## Drug-Free Workplace', '## Policy Regarding the Treatment of Co-Workers and Members of the Public\\n\\nCity policy requires employees to treat co-workers and members of the public with courtesy and respect. City employees and managers are responsible for maintaining a safe and productive workplace which is free from inappropriate workplace behavior.\\n\\n## Smoke-Free Workplace', '## Political Activity\\n\\nIt is unlawful for City employees to use public resources or personnel to engage in political activity relating to elective offices and ballot measures. City employees may not engage in political activities while on duty or in the workplace. Employees may not use City resources, such as photocopier or fax machines, telephones, postage, or email, for political activities. The ban on engaging in political activity while on duty prohibits such activities as circulating petitions, addressing campaign mailers or engaging in any other political activities that use City resources or divert employees from their assigned duties.', '## Use of City and County Property for Business Purposes Only\\n\\nNo officer or employee may use, nor allow any other r person to use, City resources for any non-City business purpose. Use of City resources fofor personal, political, employee organization or other non-City business is strictly prohibited. City resources include, but are not limited to, facilities, equipment, devices, telephones, computers, copier, fax machine, email, internet access, supplies and any time for which you are receiving compensation from the City. Inappropriate uses of City resources include, but are not limited to: online gambling; viewing sports events online; playing games, streaming video or music on a work computer; viewing or distributing materials that are not related to City business or that are sexually explicit; and frequent talking on a personal cell phone or texting during work hours.', \"The safety and well-being of our employees is very important, and in order to promote a safe and healthy work environment, the City works to identify and eliminate employee exposures to avoidable hazards and conditions that can lead to injury or illness. City departments have Injury and Illness Prevention Programs that comply with federal and state regulations, laws, and statutes in order to help maintain a safe and healthful work environment.\\n\\nSafety is every City employee's responsibility. All employees are required to remain alert and to correct hazardous conditions and unsafe acts-if it is safe to do so-and to report unsafe conditions to their supervisors.\"]
\n",
+ "
\n",
+ "
\n",
+ "
1
\n",
+ "
['Most full time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. Unused sick leave accrued under the Civil Service Rules may be accumulated from year to year up to a maximum of 130 8-hour working days.\\n\\nSome employees may be entitled to accrue sick leave under Chapter 12W of the Administrative Code. Please contact your departmental personnel officer for more information.', 'Sick leave with pay is a privilege under the Civil Service Rules, Charter and City Ordinance.\\n\\nMost full time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. Unused sick leave accrued under the Civil Service Rules may be accumulated from year to year up to a maximum of 130 8-hour working days.', '## Accrual of Paid Sick Leave\\n\\nSick leave with pay is a privilege under the Civil Service Rules, Charter and City Ordinance.', 'The maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.\\n\\n| Year of Service 12-Month Max. Entitlement | Maximum Accumulation | Maximum Accumulation |\\n|-----------------------------------------------------------|-----------------------------------------------------------|------------------------|\\n| | 1 through 5 years 80 hours (10 days) 320 hours (40 days) | |\\n| More than 5 years 120 hours (15 days) 360 hours (45 days) | | |\\n| More than 15 years 160 hours (20 days) 400 hours | | (50 days) |', 'You may not use sick leave with pay accrued under the Civil Service Rules during your first 6 months of employment with the City.\\n\\nYou may not use sick leave for reasons not set forth th in this Handbook, the Civil Service Rules, the applicable collective bargaining agreement or other applicable laws. Misuse of sick leave is grounds for discipline, up to and including termination.']
\n",
+ "
\n",
+ "
\n",
+ "
2
\n",
+ "
['The following employees are eligible for health coverage:\\n\\n- (1) All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours;\\n- (2) All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours; and\\n- (3) All other employees of the City including temporary y exempt or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12 month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours.', \"Employees in category (3) must obtain a signed certification from their department's human resources manager in order to be eligible for health coverage.\\n\\nAn employee's spouse, domestic partner and children may also be eligible for coverage through HSS. If you have enrolled a domestic partner, same sex spouse and/or their children in your health plan, it is important that you seek tax advice from a qualified professional regarding the tax consequences of such enrollment. A detailed list of eligibility requirements and necessary documentation for enrolling employee dependents is available on the HSS website at www.myhss.org/benefits/ccsf.html .\", 'Please note that the information in this section is subject to change. You should consult with HSS if you have any questions at (415) 554-1750.\\n\\n## Eligibility\\n\\nThe following employees are eligible for health coverage:', \"Coverage for a new employee in category (1) or (2) listed above starts on the first day of the coverage period following his or her start work date, provided an enrollment application and other required documentation has been submitted to HSS by applicable deadlines.\\n\\nEmployees in category (3) must obtain a signed certification from their department's human resources manager in order to be eligible for health coverage.\", '- (1) All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours;\\n- (2) All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours; and\\n- (3) All other employees of the City including temporary y exempt or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12 month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n\\nCoverage for a new employee in category (1) or (2) listed above starts on the first day of the coverage period following his or her start work date, provided an enrollment application and other required documentation has been submitted to HSS by applicable deadlines.']
\n",
+ "
\n",
+ "
\n",
+ "
3
\n",
+ "
['An additional vacation entitlement will be awarded after five years of continuous service, usually 40 hours for full-time employees. After fifteen years of service, full-time employees will receive an additional 40 hours.\\n\\nThe maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.', 'The maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.\\n\\n| Year of Service 12-Month Max. Entitlement | Maximum Accumulation | Maximum Accumulation |\\n|-----------------------------------------------------------|-----------------------------------------------------------|------------------------|\\n| | 1 through 5 years 80 hours (10 days) 320 hours (40 days) | |\\n| More than 5 years 120 hours (15 days) 360 hours (45 days) | | |\\n| More than 15 years 160 hours (20 days) 400 hours | | (50 days) |', 'The City provides annual vacations for employees who work a regular schedule and who have completed one year or more of continuous service. Certain temporary exempt employees may also be eligible for vacation benefits. You are not eligible to use vacation in the first year of continuous service; however, at the end of one year of continuous service, you will be awarded a vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year and will be eligible to use accrued vacation time. For the purpose of computing vacation, most employees may be credited with no more than 2080 hours of service in a 12month period.\\n\\nAn additional vacation entitlement will be awarded after five years of continuous service, usually 40 hours for full-time employees. After fifteen years of service, full-time employees will receive an additional 40 hours.', '## Vacation\\n\\nThe City provides annual vacations for employees who work a regular schedule and who have completed one year or more of continuous service. Certain temporary exempt employees may also be eligible for vacation benefits. You are not eligible to use vacation in the first year of continuous service; however, at the end of one year of continuous service, you will be awarded a vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year and will be eligible to use accrued vacation time. For the purpose of computing vacation, most employees may be credited with no more than 2080 hours of service in a 12month period.', 'Permanent employees may request unpaid personal leave for a period of up to twelve (12) months within any two-year period. Your department t head has discretion to grant or deny requests for personal leave. With certain exceptions, if you are a temporary or provisional employee, you may request personal leave for a maximum of one month, and only if a replacement for your position is not required.\\n\\n## Time Off for Voting']
\n",
+ "
\n",
+ "
\n",
+ "
4
\n",
+ "
['You must notify your supervisor as soon as you receive a jury summons. If you are required to report for jury duty during your working hours, you will be excused from work on the work day you perform jury service, provided you give prior notification to your supervisor. If you report for jury duty and are not selected as a juror, or if the court dismisses the proceedings early for the day, you must return to work as soon as possible.\\n\\n## Work Schedule While on Jury Duty', '## Jury Duty Leave\\n\\nYou must notify your supervisor as soon as you receive a jury summons. If you are required to report for jury duty during your working hours, you will be excused from work on the work day you perform jury service, provided you give prior notification to your supervisor. If you report for jury duty and are not selected as a juror, or if the court dismisses the proceedings early for the day, you must return to work as soon as possible.', '## Compensation While on Jury Duty\\n\\nAs a guiding principal, you are required to work or r perform jury service for the number of hours for which you are paid during that workweek. For example, if you are regularly on an alternative workweek schedule working 10-hour workdays Monday through Thursday with Friday off and you are required to serve jury duty on a Monday through Thursday, you must work a regular workday on Friday, or use personal leave to compensate for the eight hour balance. However, you and your supervisor may agree to maintain the alternative schedule, whereby you would return to the workplace to work the remaining two hours each day and continue to take Friday off.', 'As a guiding principal, you are required to work or r perform jury service for the number of hours for which you are paid during that workweek. For example, if you are regularly on an alternative workweek schedule working 10-hour workdays Monday through Thursday with Friday off and you are required to serve jury duty on a Monday through Thursday, you must work a regular workday on Friday, or use personal leave to compensate for the eight hour balance. However, you and your supervisor may agree to maintain the alternative schedule, whereby you would return to the workplace to work the remaining two hours each day and continue to take Friday off.\\n\\nYou are not entitled to a per diem pay from the City or County for which Jury Duty was served, as the City and County of San Francisco already provides regular compensation and benefits to you while performing jury service. You must notify the jury staff that you are a government employee when reporting for jury service', 'If you are summoned as a witness on behalf of the City and County of San Francisco, you are entitled to be paid for any time that you are required to serve in that capacity. If you are summoned to serve as a witness in a case involving outside employment or personal business\\n\\naffairs, you will be placed on leave without pay unless vacation leave or compensatory time is requested and granted.']
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " retrieved_contexts\n",
+ "0 ['## Smoke-Free Workplace\\n\\nSmoking is not permitted in City offices, or within n 20 feet of entrances, exits, or operable windows of public buildings.\\n\\n## Drug-Free Workplace', '## Policy Regarding the Treatment of Co-Workers and Members of the Public\\n\\nCity policy requires employees to treat co-workers and members of the public with courtesy and respect. City employees and managers are responsible for maintaining a safe and productive workplace which is free from inappropriate workplace behavior.\\n\\n## Smoke-Free Workplace', '## Political Activity\\n\\nIt is unlawful for City employees to use public resources or personnel to engage in political activity relating to elective offices and ballot measures. City employees may not engage in political activities while on duty or in the workplace. Employees may not use City resources, such as photocopier or fax machines, telephones, postage, or email, for political activities. The ban on engaging in political activity while on duty prohibits such activities as circulating petitions, addressing campaign mailers or engaging in any other political activities that use City resources or divert employees from their assigned duties.', '## Use of City and County Property for Business Purposes Only\\n\\nNo officer or employee may use, nor allow any other r person to use, City resources for any non-City business purpose. Use of City resources fofor personal, political, employee organization or other non-City business is strictly prohibited. City resources include, but are not limited to, facilities, equipment, devices, telephones, computers, copier, fax machine, email, internet access, supplies and any time for which you are receiving compensation from the City. Inappropriate uses of City resources include, but are not limited to: online gambling; viewing sports events online; playing games, streaming video or music on a work computer; viewing or distributing materials that are not related to City business or that are sexually explicit; and frequent talking on a personal cell phone or texting during work hours.', \"The safety and well-being of our employees is very important, and in order to promote a safe and healthy work environment, the City works to identify and eliminate employee exposures to avoidable hazards and conditions that can lead to injury or illness. City departments have Injury and Illness Prevention Programs that comply with federal and state regulations, laws, and statutes in order to help maintain a safe and healthful work environment.\\n\\nSafety is every City employee's responsibility. All employees are required to remain alert and to correct hazardous conditions and unsafe acts-if it is safe to do so-and to report unsafe conditions to their supervisors.\"]\n",
+ "1 ['Most full time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. Unused sick leave accrued under the Civil Service Rules may be accumulated from year to year up to a maximum of 130 8-hour working days.\\n\\nSome employees may be entitled to accrue sick leave under Chapter 12W of the Administrative Code. Please contact your departmental personnel officer for more information.', 'Sick leave with pay is a privilege under the Civil Service Rules, Charter and City Ordinance.\\n\\nMost full time employees earn 13 8-hour working days per year of paid sick leave under the Civil Service Rules. Unused sick leave accrued under the Civil Service Rules may be accumulated from year to year up to a maximum of 130 8-hour working days.', '## Accrual of Paid Sick Leave\\n\\nSick leave with pay is a privilege under the Civil Service Rules, Charter and City Ordinance.', 'The maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.\\n\\n| Year of Service 12-Month Max. Entitlement | Maximum Accumulation | Maximum Accumulation |\\n|-----------------------------------------------------------|-----------------------------------------------------------|------------------------|\\n| | 1 through 5 years 80 hours (10 days) 320 hours (40 days) | |\\n| More than 5 years 120 hours (15 days) 360 hours (45 days) | | |\\n| More than 15 years 160 hours (20 days) 400 hours | | (50 days) |', 'You may not use sick leave with pay accrued under the Civil Service Rules during your first 6 months of employment with the City.\\n\\nYou may not use sick leave for reasons not set forth th in this Handbook, the Civil Service Rules, the applicable collective bargaining agreement or other applicable laws. Misuse of sick leave is grounds for discipline, up to and including termination.']\n",
+ "2 ['The following employees are eligible for health coverage:\\n\\n- (1) All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours;\\n- (2) All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours; and\\n- (3) All other employees of the City including temporary y exempt or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12 month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours.', \"Employees in category (3) must obtain a signed certification from their department's human resources manager in order to be eligible for health coverage.\\n\\nAn employee's spouse, domestic partner and children may also be eligible for coverage through HSS. If you have enrolled a domestic partner, same sex spouse and/or their children in your health plan, it is important that you seek tax advice from a qualified professional regarding the tax consequences of such enrollment. A detailed list of eligibility requirements and necessary documentation for enrolling employee dependents is available on the HSS website at www.myhss.org/benefits/ccsf.html .\", 'Please note that the information in this section is subject to change. You should consult with HSS if you have any questions at (415) 554-1750.\\n\\n## Eligibility\\n\\nThe following employees are eligible for health coverage:', \"Coverage for a new employee in category (1) or (2) listed above starts on the first day of the coverage period following his or her start work date, provided an enrollment application and other required documentation has been submitted to HSS by applicable deadlines.\\n\\nEmployees in category (3) must obtain a signed certification from their department's human resources manager in order to be eligible for health coverage.\", '- (1) All permanent employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours;\\n- (2) All regularly scheduled provisional employees of the City whose normal work week at the time of inclusion in the system is not less than 20 hours; and\\n- (3) All other employees of the City including temporary y exempt or \"as needed\" employees who have worked more than 1040 hours in any consecutive 12 month period, and whose normal work week at the time of inclusion in the system is not less than 20 hours.\\n\\nCoverage for a new employee in category (1) or (2) listed above starts on the first day of the coverage period following his or her start work date, provided an enrollment application and other required documentation has been submitted to HSS by applicable deadlines.']\n",
+ "3 ['An additional vacation entitlement will be awarded after five years of continuous service, usually 40 hours for full-time employees. After fifteen years of service, full-time employees will receive an additional 40 hours.\\n\\nThe maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.', 'The maximum vacation entitlement in any 12 month period and maximum accrual permitted for most employees are provided in the chart on the following page.\\n\\n| Year of Service 12-Month Max. Entitlement | Maximum Accumulation | Maximum Accumulation |\\n|-----------------------------------------------------------|-----------------------------------------------------------|------------------------|\\n| | 1 through 5 years 80 hours (10 days) 320 hours (40 days) | |\\n| More than 5 years 120 hours (15 days) 360 hours (45 days) | | |\\n| More than 15 years 160 hours (20 days) 400 hours | | (50 days) |', 'The City provides annual vacations for employees who work a regular schedule and who have completed one year or more of continuous service. Certain temporary exempt employees may also be eligible for vacation benefits. You are not eligible to use vacation in the first year of continuous service; however, at the end of one year of continuous service, you will be awarded a vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year and will be eligible to use accrued vacation time. For the purpose of computing vacation, most employees may be credited with no more than 2080 hours of service in a 12month period.\\n\\nAn additional vacation entitlement will be awarded after five years of continuous service, usually 40 hours for full-time employees. After fifteen years of service, full-time employees will receive an additional 40 hours.', '## Vacation\\n\\nThe City provides annual vacations for employees who work a regular schedule and who have completed one year or more of continuous service. Certain temporary exempt employees may also be eligible for vacation benefits. You are not eligible to use vacation in the first year of continuous service; however, at the end of one year of continuous service, you will be awarded a vacation allowance at the rate of .0385 of an hour for each hour of paid service in the preceding year and will be eligible to use accrued vacation time. For the purpose of computing vacation, most employees may be credited with no more than 2080 hours of service in a 12month period.', 'Permanent employees may request unpaid personal leave for a period of up to twelve (12) months within any two-year period. Your department t head has discretion to grant or deny requests for personal leave. With certain exceptions, if you are a temporary or provisional employee, you may request personal leave for a maximum of one month, and only if a replacement for your position is not required.\\n\\n## Time Off for Voting']\n",
+ "4 ['You must notify your supervisor as soon as you receive a jury summons. If you are required to report for jury duty during your working hours, you will be excused from work on the work day you perform jury service, provided you give prior notification to your supervisor. If you report for jury duty and are not selected as a juror, or if the court dismisses the proceedings early for the day, you must return to work as soon as possible.\\n\\n## Work Schedule While on Jury Duty', '## Jury Duty Leave\\n\\nYou must notify your supervisor as soon as you receive a jury summons. If you are required to report for jury duty during your working hours, you will be excused from work on the work day you perform jury service, provided you give prior notification to your supervisor. If you report for jury duty and are not selected as a juror, or if the court dismisses the proceedings early for the day, you must return to work as soon as possible.', '## Compensation While on Jury Duty\\n\\nAs a guiding principal, you are required to work or r perform jury service for the number of hours for which you are paid during that workweek. For example, if you are regularly on an alternative workweek schedule working 10-hour workdays Monday through Thursday with Friday off and you are required to serve jury duty on a Monday through Thursday, you must work a regular workday on Friday, or use personal leave to compensate for the eight hour balance. However, you and your supervisor may agree to maintain the alternative schedule, whereby you would return to the workplace to work the remaining two hours each day and continue to take Friday off.', 'As a guiding principal, you are required to work or r perform jury service for the number of hours for which you are paid during that workweek. For example, if you are regularly on an alternative workweek schedule working 10-hour workdays Monday through Thursday with Friday off and you are required to serve jury duty on a Monday through Thursday, you must work a regular workday on Friday, or use personal leave to compensate for the eight hour balance. However, you and your supervisor may agree to maintain the alternative schedule, whereby you would return to the workplace to work the remaining two hours each day and continue to take Friday off.\\n\\nYou are not entitled to a per diem pay from the City or County for which Jury Duty was served, as the City and County of San Francisco already provides regular compensation and benefits to you while performing jury service. You must notify the jury staff that you are a government employee when reporting for jury service', 'If you are summoned as a witness on behalf of the City and County of San Francisco, you are entitled to be paid for any time that you are required to serve in that capacity. If you are summoned to serve as a witness in a case involving outside employment or personal business\\n\\naffairs, you will be placed on leave without pay unless vacation leave or compensatory time is requested and granted.']"
+ ]
+ },
+ "execution_count": 41,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data[['retrieved_contexts']].head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "10",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "11",
+ "metadata": {},
+ "source": [
+ "#### **4. Visualizing the Metrics**\n",
+ "\n",
+ "Let's create bar charts to visualize each metric for the different user inputs."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "12",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def plot_metric(metric):\n",
+ " data['short_user_input'] = data['user_input'].apply(lambda x: x[:10] + '...' if len(x) > 10 else x)\n",
+ " plt.figure(figsize=(7, 4))\n",
+ " sns.barplot(x='short_user_input', y=metric, data=data, hue='short_user_input', palette='viridis', legend=False)\n",
+ " plt.xticks(rotation=75, ha='right', fontsize=8)\n",
+ " plt.ylim(0, 1.1)\n",
+ " plt.title(f'{metric.replace(\"_\", \" \").title()} for Each User Input')\n",
+ " plt.ylabel(metric.replace(\"_\", \" \").title())\n",
+ " plt.xlabel('User Input')\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "210298cf-b285-4eea-b980-0190520cc20d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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BY3u6+7uXq6TelGcnZ2FLkGrsD3UsT3UsT3UsT1eYluoY3uoK6o9ZDJZkZ1BrxM0lFWpUgUSiaTQpP7k5GRYWlq+9b6bN2/Ghg0b4O/vDxcXF42fWyKRiC6Uie31vgvbQx3bQx3bQx3b4yW2hTq2h7oPaQ9BJ/obGBigfv36apP0lZP2GzZs+Mb7bdy4Eb/88gs2bdoEd3f3siiViIiIqFQJPnw5cuRIzJo1C25ubvDw8MDWrVuRk5ODXr16AQBmzpwJGxsbTJs2DcCLIcs1a9ZgxYoVsLW1RWJiIgDA2NgYJiYmgr0OIiIiog8heCjr3LkzUlJSsGbNGiQmJqJevXrYtGmTavgyPj4eurovO/QCAgKQn5+Pr776Su1xJk6ciEmTJpVp7UREREQlRfBQBgBDhgzBkCFDirxt+/btaj//+++/ZVESERERUZkS/OSxRERERMRQRkRERKQVGMqIiIiItABDGREREZEWYCgjIiIi0gIMZURERERagKGMiIiISAswlBERERFpAYYyIiIiIi3AUEZERESkBRjKiIiIiLQAQxkRERGRFmAoIyIiItICDGVEREREWoChjIiIiEgLMJQRERERaQGGMiIiIiItwFBGREREpAUYyoiIiIi0AEMZERERkRZgKCMiIiLSAgxlRERERFqAoYyIiIhICzCUEREREWkBhjIiIiIiLcBQRkRERKQFGMqIiIiItABDGREREZEWYCgjIiIi0gIMZURERERagKGMiIiISAswlBERERFpAYYyIiIiIi3AUEZERESkBRjKiIiIiLQAQxkRERGRFmAoIyIiItICDGVEREREWoChjIiIiEgLMJQRERERaQGGMiIiIiItwFBGREREpAUYyoiIiIi0AEMZERERkRZgKCMiIiLSAloRynbs2IF27drB3d0dffv2RXh4+Fv3P3z4MDp16gR3d3d069YNJ0+eLKNKiYiIiEqH4KEsJCQEfn5+mDBhAoKCguDi4oLRo0cjOTm5yP3/++8/TJs2DX369EFwcDDat2+PCRMm4O7du2VcOREREVHJETyU+fv7o1+/fujduzfq1KmDhQsXwtDQEIGBgUXuv23bNrRq1QpffPEFateuja+//hqurq74448/yrhyIiIiopKjJ+STS6VS3Lp1C2PHjlVt09XVRfPmzXH16tUi73Pt2jWMGDFCbVvLli1x7Nix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",
+ "text/plain": [
+ "
How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules?
\n",
+ "
1.000000
\n",
+ "
0.500000
\n",
+ "
1.000000
\n",
+ "
0.986973
\n",
+ "
\n",
+ "
\n",
+ "
2
\n",
+ "
What are the three categories of employees eligible for health coverage?
\n",
+ "
0.700000
\n",
+ "
1.000000
\n",
+ "
0.800000
\n",
+ "
0.981254
\n",
+ "
\n",
+ "
\n",
+ "
3
\n",
+ "
How long must an employee wait before using vacation time after starting employment?
\n",
+ "
0.416667
\n",
+ "
0.666667
\n",
+ "
1.000000
\n",
+ "
0.979251
\n",
+ "
\n",
+ "
\n",
+ "
6
\n",
+ "
How long is the normal probationary period for permanent civil service positions?
\n",
+ "
1.000000
\n",
+ "
0.666667
\n",
+ "
1.000000
\n",
+ "
0.000000
\n",
+ "
\n",
+ "
\n",
+ "
7
\n",
+ "
What are employees required to do in case of a catastrophic event while off duty?
\n",
+ "
0.866667
\n",
+ "
0.666667
\n",
+ "
1.000000
\n",
+ "
0.987241
\n",
+ "
\n",
+ "
\n",
+ "
8
\n",
+ "
What is the city's policy on accepting gifts from subordinates?
\n",
+ "
0.887500
\n",
+ "
1.000000
\n",
+ "
0.666667
\n",
+ "
0.956919
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " user_input \\\n",
+ "1 How many days of paid sick leave do most full-time employees earn per year under Civil Service Rules? \n",
+ "2 What are the three categories of employees eligible for health coverage? \n",
+ "3 How long must an employee wait before using vacation time after starting employment? \n",
+ "6 How long is the normal probationary period for permanent civil service positions? \n",
+ "7 What are employees required to do in case of a catastrophic event while off duty? \n",
+ "8 What is the city's policy on accepting gifts from subordinates? \n",
+ "\n",
+ " context_precision context_recall faithfulness answer_relevancy \n",
+ "1 1.000000 0.500000 1.000000 0.986973 \n",
+ "2 0.700000 1.000000 0.800000 0.981254 \n",
+ "3 0.416667 0.666667 1.000000 0.979251 \n",
+ "6 1.000000 0.666667 1.000000 0.000000 \n",
+ "7 0.866667 0.666667 1.000000 0.987241 \n",
+ "8 0.887500 1.000000 0.666667 0.956919 "
+ ]
+ },
+ "execution_count": 42,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "low_metrics = data[\n",
+ " (data['context_precision'] < 0.7) |\n",
+ " (data['context_recall'] < 0.7) |\n",
+ " (data['faithfulness'] < 0.9) |\n",
+ " (data['answer_relevancy'] < 0.7)\n",
+ "]\n",
+ "\n",
+ "low_metrics[['user_input', 'context_precision', 'context_recall', 'faithfulness', 'answer_relevancy']]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "19",
+ "metadata": {},
+ "source": [
+ "---"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.0"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/DocQA/docker/compose-cpu.yaml b/examples/DocQA/docker/compose-cpu.yaml
new file mode 100644
index 000000000..9b9ea0bad
--- /dev/null
+++ b/examples/DocQA/docker/compose-cpu.yaml
@@ -0,0 +1,53 @@
+services:
+ chromadb:
+ image: ghcr.io/chroma-core/chroma:latest
+ env_file: "docqa_env"
+ environment:
+ - IS_PERSISTENT=TRUE
+ - CHROMA_HOST_PORT=${CHROMA_PORT}
+ network_mode: "host"
+ volumes:
+ - ${DOC_PATH}:/chroma/chroma
+ tty: true
+ ports:
+ - "6000:6000"
+ ollama:
+ image: ollama/ollama:latest
+ env_file: "docqa_env"
+ network_mode: "host"
+ environment:
+ - MODEL_NAME=${MODEL_NAME}
+ - OLLAMA_KEEP_ALIVE=99h
+ - OLLAMA_HOST=127.0.0.1:14343
+ volumes:
+ - ollama:/root/.ollama # this solution synchronizes with the docker volume and loads the model rocket fast
+ - ./ollama_start.sh:/root/ollama_start.sh
+ ports:
+ - "14343:14343"
+ tty: true
+ restart: always
+ entrypoint: ["bash", "/root/ollama_start.sh"]
+ llamastack:
+ image: llamastack/distribution-ollama:0.0.56
+ env_file: "docqa_env"
+ network_mode: "host"
+ tty: true
+ volumes:
+ - ~/.llama:/root/.llama
+ # Link to ollama run.yaml file
+ - ./llama_stack_run.yaml:/root/my-run.yaml
+ - ../../DocQA:/root/DocQA
+ - ${DOC_PATH}:/root/rag_data/
+ - ./llama_stack_start.sh:/root/llama_stack_start.sh
+ ports:
+ - "5000:5000" # for llama-stack
+ - "7860:7860" # for UI
+ # Hack: wait for ollama server to start before starting docker
+ entrypoint: ["bash", "/root/llama_stack_start.sh"]
+ #entrypoint: bash -c "sleep 60; python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
+ deploy:
+ restart_policy:
+ condition: "no"
+
+volumes:
+ ollama:
diff --git a/examples/DocQA/docker/compose-gpu.yaml b/examples/DocQA/docker/compose-gpu.yaml
new file mode 100644
index 000000000..f7a5b6fde
--- /dev/null
+++ b/examples/DocQA/docker/compose-gpu.yaml
@@ -0,0 +1,59 @@
+services:
+ chromadb:
+ image: ghcr.io/chroma-core/chroma:latest
+ env_file: "docqa_env"
+ environment:
+ - IS_PERSISTENT=TRUE
+ - CHROMA_HOST_PORT=${CHROMA_PORT}
+ network_mode: "host"
+ volumes:
+ - ${DOC_PATH}:/chroma/chroma
+ tty: true
+ ports:
+ - "6000:6000"
+ ollama:
+ image: ollama/ollama:latest
+ env_file: "docqa_env"
+ network_mode: "host"
+ environment:
+ - MODEL_NAME=${MODEL_NAME}
+ - OLLAMA_KEEP_ALIVE=99h
+ - OLLAMA_HOST=127.0.0.1:14343
+ volumes:
+ - ollama:/root/.ollama # this solution synchronizes with the docker volume and loads the model rocket fast
+ - ./ollama_start.sh:/root/ollama_start.sh
+ ports:
+ - "14343:14343"
+ tty: true
+ deploy:
+ resources: # enable GPUs
+ reservations:
+ devices:
+ - driver: nvidia
+ capabilities: [gpu]
+ restart: always
+ entrypoint: ["bash", "/root/ollama_start.sh"]
+ llamastack:
+ image: llamastack/distribution-ollama:0.0.56
+ env_file: "docqa_env"
+ network_mode: "host"
+ tty: true
+ volumes:
+ - ~/.llama:/root/.llama
+ # Link to ollama run.yaml file
+ - ./llama_stack_run.yaml:/root/my-run.yaml
+ - ../../DocQA:/root/DocQA
+ - ${DOC_PATH}:/root/rag_data/
+ - ./llama_stack_start.sh:/root/llama_stack_start.sh
+ ports:
+ - "5000:5000" # for llama-stack
+ - "7860:7860" # for UI
+ # Hack: wait for ollama server to start before starting docker
+ entrypoint: ["bash", "/root/llama_stack_start.sh"]
+ #entrypoint: bash -c "sleep 60; python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
+ deploy:
+ restart_policy:
+ condition: "no"
+
+volumes:
+ ollama:
diff --git a/examples/DocQA/docker/docqa_env_template b/examples/DocQA/docker/docqa_env_template
new file mode 100644
index 000000000..2a45408aa
--- /dev/null
+++ b/examples/DocQA/docker/docqa_env_template
@@ -0,0 +1,7 @@
+DOC_PATH=/path/to/your/llama-stack-apps/examples/DocQA/example_data
+MODEL_NAME=llama3.2:1b-instruct-fp16
+HOST=localhost
+LLAMA_STACK_PORT=5000
+CHROMA_PORT=6000
+GRADIO_SERVER_PORT=7860
+USE_GPU_FOR_DOC_INGESTION=false
diff --git a/examples/DocQA/docker/llama_stack_run.yaml b/examples/DocQA/docker/llama_stack_run.yaml
new file mode 100644
index 000000000..3d67c8200
--- /dev/null
+++ b/examples/DocQA/docker/llama_stack_run.yaml
@@ -0,0 +1,54 @@
+version: '2'
+built_at: '2024-10-08T17:40:45.325529'
+image_name: local
+docker_image: null
+conda_env: local
+apis:
+- shields
+- agents
+- models
+- memory
+- memory_banks
+- inference
+- safety
+providers:
+ inference:
+ - provider_id: remote::ollama
+ provider_type: remote::ollama
+ config:
+ url: http://127.0.0.1:14343
+ memory:
+ - provider_id: remote::chromadb
+ provider_type: remote::chromadb
+ config:
+ host: localhost
+ port: 6000
+ protocol: http
+ safety:
+ - provider_id: inline::llama-guard-0
+ provider_type: inline::llama-guard
+ config:
+ excluded_categories: []
+ agents:
+ - provider_id: inline::meta-reference-0
+ provider_type: inline::meta-reference
+ config:
+ persistence_store:
+ namespace: null
+ type: sqlite
+ db_path: ${HOME}/.llama/runtime/kvstore.db
+ telemetry:
+ - provider_id: inline::meta-reference-0
+ provider_type: inline::meta-reference
+ config: {}
+metadata_store: null
+models:
+- metadata: {}
+ model_id: meta-llama/Llama-3.2-1B-Instruct
+ provider_id: null
+ provider_model_id: llama3.2:1b-instruct-fp16
+shields: []
+memory_banks: []
+datasets: []
+scoring_fns: []
+eval_tasks: []
diff --git a/examples/DocQA/docker/llama_stack_start.sh b/examples/DocQA/docker/llama_stack_start.sh
new file mode 100644
index 000000000..a7af16be7
--- /dev/null
+++ b/examples/DocQA/docker/llama_stack_start.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+sleep 45
+echo "-----starting to llama-stack docker now---------"
+pip install gradio
+
+if [ "$USE_GPU_FOR_DOC_INGESTION" = true ]; then
+ echo "Using GPU to ingest files"
+ pip install docling
+ python /root/DocQA/scripts/ingest_files.py --input_dir /root/rag_data/
+fi
+echo "starting the llama-stack server"
+python -m llama_stack.distribution.server.server --yaml-config /root/my-run.yaml --disable-ipv6&
+sleep 30
+echo "---------running the RAG app--------------"
+python /root/DocQA/app.py
diff --git a/examples/DocQA/docker/ollama_start.sh b/examples/DocQA/docker/ollama_start.sh
new file mode 100644
index 000000000..d38a90c79
--- /dev/null
+++ b/examples/DocQA/docker/ollama_start.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+echo "-------------start to serve------------"
+OLLAMA_HOST=127.0.0.1:14343 /usr/bin/ollama serve &
+echo "Running ollama model: $MODEL_NAME"
+sleep 5
+OLLAMA_HOST=127.0.0.1:14343 /usr/bin/ollama run $MODEL_NAME
diff --git a/examples/DocQA/docker/run_RAG.sh b/examples/DocQA/docker/run_RAG.sh
new file mode 100755
index 000000000..3380fbe6a
--- /dev/null
+++ b/examples/DocQA/docker/run_RAG.sh
@@ -0,0 +1,12 @@
+set -a
+source docqa_env
+echo $DOC_PATH
+# Run GPU version of ollama docker
+if [ "$USE_GPU_FOR_DOC_INGESTION" = true ]; then
+ echo "Running with GPU"
+ docker compose --file compose-gpu.yaml up
+else
+# Run CPU version of ollama docker
+ echo "Running with CPU only"
+ docker compose --file compose-cpu.yaml up
+fi
diff --git a/examples/DocQA/example_data/llama_3.1.md b/examples/DocQA/example_data/llama_3.1.md
new file mode 100644
index 000000000..af2d4850b
--- /dev/null
+++ b/examples/DocQA/example_data/llama_3.1.md
@@ -0,0 +1,977 @@
+## Model Information
+
+The Meta Llama 3.1 collection of multilingual large language models (LLMs) is a collection of pretrained and instruction tuned generative models in 8B, 70B and 405B sizes (text in/text out). The Llama 3.1 instruction tuned text only models (8B, 70B, 405B) are optimized for multilingual dialogue use cases and outperform many of the available open source and closed chat models on common industry benchmarks.
+
+Model developer: Meta
+
+Model Architecture: Llama 3.1 is an auto-regressive language model that uses an optimized transformer architecture. The tuned versions use supervised fine-tuning (SFT) and reinforcement learning with human feedback (RLHF) to align with human preferences for helpfulness and safety.
+
+
+
+
+
+
+
Training Data
+
+
Params
+
+
Input modalities
+
+
Output modalities
+
+
Context length
+
+
GQA
+
+
Token count
+
+
Knowledge cutoff
+
+
+
+
Llama 3.1 (text only)
+
+
A new mix of publicly available online data.
+
+
8B
+
+
Multilingual Text
+
+
Multilingual Text and code
+
+
128k
+
+
Yes
+
+
15T+
+
+
December 2023
+
+
+
+
70B
+
+
Multilingual Text
+
+
Multilingual Text and code
+
+
128k
+
+
Yes
+
+
+
+
405B
+
+
Multilingual Text
+
+
Multilingual Text and code
+
+
128k
+
+
Yes
+
+
+
+
+
+Supported languages: English, German, French, Italian, Portuguese, Hindi, Spanish, and Thai.
+
+Llama 3.1 family of models. Token counts refer to pretraining data only. All model versions use Grouped-Query Attention (GQA) for improved inference scalability.
+
+Model Release Date: July 23, 2024.
+
+Status: This is a static model trained on an offline dataset. Future versions of the tuned models will be released as we improve model safety with community feedback.
+
+License: A custom commercial license, the Llama 3.1 Community License, is available at: [https://github.com/meta-llama/llama-models/blob/main/models/llama3_1/LICENSE](https://github.com/meta-llama/llama-models/blob/main/models/llama3_1/LICENSE)
+
+Feedback: Instructions on how to provide feedback or comments on the model can be found in the Llama Models [README](https://github.com/meta-llama/llama-models/blob/main/README.md). For more technical information about generation parameters and recipes for how to use Llama 3.1 in applications, please go [here](https://github.com/meta-llama/llama-recipes).
+
+
+## Intended Use
+
+Intended Use Cases Llama 3.1 is intended for commercial and research use in multiple languages. Instruction tuned text only models are intended for assistant-like chat, whereas pretrained models can be adapted for a variety of natural language generation tasks. The Llama 3.1 model collection also supports the ability to leverage the outputs of its models to improve other models including synthetic data generation and distillation. The Llama 3.1 Community License allows for these use cases.
+
+Out-of-scope Use in any manner that violates applicable laws or regulations (including trade compliance laws). Use in any other way that is prohibited by the Acceptable Use Policy and Llama 3.1 Community License. Use in languages beyond those explicitly referenced as supported in this model card.
+
+Note: Llama 3.1 has been trained on a broader collection of languages than the 8 supported languages. Developers may fine-tune Llama 3.1 models for languages beyond the 8 supported languages provided they comply with the Llama 3.1 Community License and the Acceptable Use Policy and in such cases are responsible for ensuring that any uses of Llama 3.1 in additional languages is done in a safe and responsible manner.
+
+
+## Hardware and Software
+
+Training Factors We used custom training libraries, Meta's custom built GPU cluster, and production infrastructure for pretraining. Fine-tuning, annotation, and evaluation were also performed on production infrastructure.
+
+Training Energy Use Training utilized a cumulative of 39.3M GPU hours of computation on H100-80GB (TDP of 700W) type hardware, per the table below. Training time is the total GPU time required for training each model and power consumption is the peak power capacity per GPU device used, adjusted for power usage efficiency.
+
+
+Training Greenhouse Gas Emissions Estimated total location-based greenhouse gas emissions were 11,390 tons CO2eq for training. Since 2020, Meta has maintained net zero greenhouse gas emissions in its global operations and matched 100% of its electricity use with renewable energy, therefore the total market-based greenhouse gas emissions for training were 0 tons CO2eq.
+
+
+
+
+
+
+
Training Time (GPU hours)
+
+
Training Power Consumption (W)
+
+
Training Location-Based Greenhouse Gas Emissions
+
+(tons CO2eq)
+
+
Training Market-Based Greenhouse Gas Emissions
+
+(tons CO2eq)
+
+
+
+
Llama 3.1 8B
+
+
1.46M
+
+
700
+
+
420
+
+
0
+
+
+
+
Llama 3.1 70B
+
+
7.0M
+
+
700
+
+
2,040
+
+
0
+
+
+
+
Llama 3.1 405B
+
+
30.84M
+
+
700
+
+
8,930
+
+
0
+
+
+
+
Total
+
+
39.3M
+
+
+
+
+
+
11,390
+
+
0
+
+
+
+
+
+
+The methodology used to determine training energy use and greenhouse gas emissions can be found [here](https://arxiv.org/pdf/2204.05149). Since Meta is openly releasing these models, the training energy use and greenhouse gas emissions will not be incurred by others.
+
+
+## Training Data
+
+Overview: Llama 3.1 was pretrained on ~15 trillion tokens of data from publicly available sources. The fine-tuning data includes publicly available instruction datasets, as well as over 25M synthetically generated examples.
+
+Data Freshness: The pretraining data has a cutoff of December 2023.
+
+
+## Benchmark scores
+
+In this section, we report the results for Llama 3.1 models on standard automatic benchmarks. For all the evaluations, we use our internal evaluations library. Details of our evals can be found [here](https://github.com/meta-llama/llama-models/blob/main/models/llama3_1/eval_details.md). We are also releasing the raw data generated as part of our evals which can be found [here](https://huggingface.co/meta-llama) in the dataset sections.
+
+### Base pretrained models
+
+
+
+
+
Category
+
+
Benchmark
+
+
# Shots
+
+
Metric
+
+
Llama 3 8B
+
+
Llama 3.1 8B
+
+
Llama 3 70B
+
+
Llama 3.1 70B
+
+
Llama 3.1 405B
+
+
+
+
General
+
+
MMLU
+
+
5
+
+
macro_avg/acc_char
+
+
66.7
+
+
66.7
+
+
79.5
+
+
79.3
+
+
85.2
+
+
+
+
MMLU-Pro (CoT)
+
+
5
+
+
macro_avg/acc_char
+
+
36.2
+
+
37.1
+
+
55.0
+
+
53.8
+
+
61.6
+
+
+
+
AGIEval English
+
+
3-5
+
+
average/acc_char
+
+
47.1
+
+
47.8
+
+
63.0
+
+
64.6
+
+
71.6
+
+
+
+
CommonSenseQA
+
+
7
+
+
acc_char
+
+
72.6
+
+
75.0
+
+
83.8
+
+
84.1
+
+
85.8
+
+
+
+
Winogrande
+
+
5
+
+
acc_char
+
+
-
+
+
60.5
+
+
-
+
+
83.3
+
+
86.7
+
+
+
+
BIG-Bench Hard (CoT)
+
+
3
+
+
average/em
+
+
61.1
+
+
64.2
+
+
81.3
+
+
81.6
+
+
85.9
+
+
+
+
ARC-Challenge
+
+
25
+
+
acc_char
+
+
79.4
+
+
79.7
+
+
93.1
+
+
92.9
+
+
96.1
+
+
+
+
Knowledge reasoning
+
+
TriviaQA-Wiki
+
+
5
+
+
em
+
+
78.5
+
+
77.6
+
+
89.7
+
+
89.8
+
+
91.8
+
+
+
+
Reading comprehension
+
+
SQuAD
+
+
1
+
+
em
+
+
76.4
+
+
77.0
+
+
85.6
+
+
81.8
+
+
89.3
+
+
+
+
QuAC (F1)
+
+
1
+
+
f1
+
+
44.4
+
+
44.9
+
+
51.1
+
+
51.1
+
+
53.6
+
+
+
+
BoolQ
+
+
0
+
+
acc_char
+
+
75.7
+
+
75.0
+
+
79.0
+
+
79.4
+
+
80.0
+
+
+
+
DROP (F1)
+
+
3
+
+
f1
+
+
58.4
+
+
59.5
+
+
79.7
+
+
79.6
+
+
84.8
+
+
+
+
+
+
+### Instruction tuned models
+
+
+
+
+
Category
+
+
Benchmark
+
+
# Shots
+
+
Metric
+
+
Llama 3 8B Instruct
+
+
Llama 3.1 8B Instruct
+
+
Llama 3 70B Instruct
+
+
Llama 3.1 70B Instruct
+
+
Llama 3.1 405B Instruct
+
+
+
+
General
+
+
MMLU
+
+
5
+
+
macro_avg/acc
+
+
68.5
+
+
69.4
+
+
82.0
+
+
83.6
+
+
87.3
+
+
+
+
MMLU (CoT)
+
+
0
+
+
macro_avg/acc
+
+
65.3
+
+
73.0
+
+
80.9
+
+
86.0
+
+
88.6
+
+
+
+
MMLU-Pro (CoT)
+
+
5
+
+
macro_avg/acc
+
+
45.5
+
+
48.3
+
+
63.4
+
+
66.4
+
+
73.3
+
+
+
+
IFEval
+
+
+
+
+
+
76.8
+
+
80.4
+
+
82.9
+
+
87.5
+
+
88.6
+
+
+
+
Reasoning
+
+
ARC-C
+
+
0
+
+
acc
+
+
82.4
+
+
83.4
+
+
94.4
+
+
94.8
+
+
96.9
+
+
+
+
GPQA
+
+
0
+
+
em
+
+
34.6
+
+
30.4
+
+
39.5
+
+
46.7
+
+
50.7
+
+
+
+
Code
+
+
HumanEval
+
+
0
+
+
pass@1
+
+
60.4
+
+
72.6
+
+
81.7
+
+
80.5
+
+
89.0
+
+
+
+
MBPP ++ base version
+
+
0
+
+
pass@1
+
+
70.6
+
+
72.8
+
+
82.5
+
+
86.0
+
+
88.6
+
+
+
+
Multipl-E HumanEval
+
+
0
+
+
pass@1
+
+
-
+
+
50.8
+
+
-
+
+
65.5
+
+
75.2
+
+
+
+
Multipl-E MBPP
+
+
0
+
+
pass@1
+
+
-
+
+
52.4
+
+
-
+
+
62.0
+
+
65.7
+
+
+
+
Math
+
+
GSM-8K (CoT)
+
+
8
+
+
em_maj1@1
+
+
80.6
+
+
84.5
+
+
93.0
+
+
95.1
+
+
96.8
+
+
+
+
MATH (CoT)
+
+
0
+
+
final_em
+
+
29.1
+
+
51.9
+
+
51.0
+
+
68.0
+
+
73.8
+
+
+
+
Tool Use
+
+
API-Bank
+
+
0
+
+
acc
+
+
48.3
+
+
82.6
+
+
85.1
+
+
90.0
+
+
92.0
+
+
+
+
BFCL
+
+
0
+
+
acc
+
+
60.3
+
+
76.1
+
+
83.0
+
+
84.8
+
+
88.5
+
+
+
+
Gorilla Benchmark API Bench
+
+
0
+
+
acc
+
+
1.7
+
+
8.2
+
+
14.7
+
+
29.7
+
+
35.3
+
+
+
+
Nexus (0-shot)
+
+
0
+
+
macro_avg/acc
+
+
18.1
+
+
38.5
+
+
47.8
+
+
56.7
+
+
58.7
+
+
+
+
Multilingual
+
+
Multilingual MGSM (CoT)
+
+
0
+
+
em
+
+
-
+
+
68.9
+
+
-
+
+
86.9
+
+
91.6
+
+
+
+
+#### Multilingual benchmarks
+
+
+
+
Category
+
+
Benchmark
+
+
Language
+
+
Llama 3.1 8B Instruct
+
+
Llama 3.1 70B Instruct
+
+
Llama 3.1 405B Instruct
+
+
+
+
General
+
+
MMLU (5-shot, macro_avg/acc)
+
+
Portuguese
+
+
62.12
+
+
80.13
+
+
84.95
+
+
+
+
Spanish
+
+
62.45
+
+
80.05
+
+
85.08
+
+
+
+
Italian
+
+
61.63
+
+
80.4
+
+
85.04
+
+
+
+
German
+
+
60.59
+
+
79.27
+
+
84.36
+
+
+
+
French
+
+
62.34
+
+
79.82
+
+
84.66
+
+
+
+
Hindi
+
+
50.88
+
+
74.52
+
+
80.31
+
+
+
+
Thai
+
+
50.32
+
+
72.95
+
+
78.21
+
+
+
+
+
+
+## Responsibility & Safety
+
+As part of our Responsible release approach, we followed a three-pronged strategy to managing trust & safety risks:
+
+
+
+* Enable developers to deploy helpful, safe and flexible experiences for their target audience and for the use cases supported by Llama.
+* Protect developers against adversarial users aiming to exploit Llama capabilities to potentially cause harm.
+* Provide protections for the community to help prevent the misuse of our models.
+
+
+### Responsible deployment
+
+Llama is a foundational technology designed to be used in a variety of use cases, examples on how Meta’s Llama models have been responsibly deployed can be found in our [Community Stories webpage](https://llama.meta.com/community-stories/). Our approach is to build the most helpful models enabling the world to benefit from the technology power, by aligning our model safety for the generic use cases addressing a standard set of harms. Developers are then in the driver seat to tailor safety for their use case, defining their own policy and deploying the models with the necessary safeguards in their Llama systems. Llama 3.1 was developed following the best practices outlined in our Responsible Use Guide, you can refer to the [Responsible Use Guide](https://llama.meta.com/responsible-use-guide/) to learn more.
+
+
+#### Llama 3.1 instruct
+
+Our main objectives for conducting safety fine-tuning are to provide the research community with a valuable resource for studying the robustness of safety fine-tuning, as well as to offer developers a readily available, safe, and powerful model for various applications to reduce the developer workload to deploy safe AI systems. For more details on the safety mitigations implemented please read the Llama 3 paper.
+
+Fine-tuning data
+
+We employ a multi-faceted approach to data collection, combining human-generated data from our vendors with synthetic data to mitigate potential safety risks. We’ve developed many large language model (LLM)-based classifiers that enable us to thoughtfully select high-quality prompts and responses, enhancing data quality control.
+
+Refusals and Tone
+
+Building on the work we started with Llama 3, we put a great emphasis on model refusals to benign prompts as well as refusal tone. We included both borderline and adversarial prompts in our safety data strategy, and modified our safety data responses to follow tone guidelines.
+
+
+#### Llama 3.1 systems
+
+Large language models, including Llama 3.1, are not designed to be deployed in isolation but instead should be deployed as part of an overall AI system with additional safety guardrails as required. Developers are expected to deploy system safeguards when building agentic systems. Safeguards are key to achieve the right helpfulness-safety alignment as well as mitigating safety and security risks inherent to the system and any integration of the model or system with external tools.
+
+As part of our responsible release approach, we provide the community with [safeguards](https://llama.meta.com/trust-and-safety/) that developers should deploy with Llama models or other LLMs, including Llama Guard 3, Prompt Guard and Code Shield. All our [reference implementations](https://github.com/meta-llama/llama-agentic-system) demos contain these safeguards by default so developers can benefit from system-level safety out-of-the-box.
+
+
+#### New capabilities
+
+Note that this release introduces new capabilities, including a longer context window, multilingual inputs and outputs and possible integrations by developers with third party tools. Building with these new capabilities requires specific considerations in addition to the best practices that generally apply across all Generative AI use cases.
+
+Tool-use: Just like in standard software development, developers are responsible for the integration of the LLM with the tools and services of their choice. They should define a clear policy for their use case and assess the integrity of the third party services they use to be aware of the safety and security limitations when using this capability. Refer to the Responsible Use Guide for best practices on the safe deployment of the third party safeguards.
+
+Multilinguality: Llama 3.1 supports 7 languages in addition to English: French, German, Hindi, Italian, Portuguese, Spanish, and Thai. Llama may be able to output text in other languages than those that meet performance thresholds for safety and helpfulness. We strongly discourage developers from using this model to converse in non-supported languages without implementing finetuning and system controls in alignment with their policies and the best practices shared in the Responsible Use Guide.
+
+
+### Evaluations
+
+We evaluated Llama models for common use cases as well as specific capabilities. Common use cases evaluations measure safety risks of systems for most commonly built applications including chat bot, coding assistant, tool calls. We built dedicated, adversarial evaluation datasets and evaluated systems composed of Llama models and Llama Guard 3 to filter input prompt and output response. It is important to evaluate applications in context, and we recommend building dedicated evaluation dataset for your use case. Prompt Guard and Code Shield are also available if relevant to the application.
+
+Capability evaluations measure vulnerabilities of Llama models inherent to specific capabilities, for which were crafted dedicated benchmarks including long context, multilingual, tools calls, coding or memorization.
+
+Red teaming
+
+For both scenarios, we conducted recurring red teaming exercises with the goal of discovering risks via adversarial prompting and we used the learnings to improve our benchmarks and safety tuning datasets.
+
+We partnered early with subject-matter experts in critical risk areas to understand the nature of these real-world harms and how such models may lead to unintended harm for society. Based on these conversations, we derived a set of adversarial goals for the red team to attempt to achieve, such as extracting harmful information or reprogramming the model to act in a potentially harmful capacity. The red team consisted of experts in cybersecurity, adversarial machine learning, responsible AI, and integrity in addition to multilingual content specialists with background in integrity issues in specific geographic markets. .
+
+
+### Critical and other risks
+
+We specifically focused our efforts on mitigating the following critical risk areas:
+
+1. CBRNE (Chemical, Biological, Radiological, Nuclear, and Explosive materials) helpfulness
+
+To assess risks related to proliferation of chemical and biological weapons, we performed uplift testing designed to assess whether use of Llama 3.1 models could meaningfully increase the capabilities of malicious actors to plan or carry out attacks using these types of weapons.
+
+
+2. Child Safety
+
+Child Safety risk assessments were conducted using a team of experts, to assess the model’s capability to produce outputs that could result in Child Safety risks and inform on any necessary and appropriate risk mitigations via fine tuning. We leveraged those expert red teaming sessions to expand the coverage of our evaluation benchmarks through Llama 3 model development. For Llama 3, we conducted new in-depth sessions using objective based methodologies to assess the model risks along multiple attack vectors including the additional languages Llama 3 is trained on. We also partnered with content specialists to perform red teaming exercises assessing potentially violating content while taking account of market specific nuances or experiences.
+
+3. Cyber attack enablement
+
+Our cyber attack uplift study investigated whether LLMs can enhance human capabilities in hacking tasks, both in terms of skill level and speed.
+
+Our attack automation study focused on evaluating the capabilities of LLMs when used as autonomous agents in cyber offensive operations, specifically in the context of ransomware attacks. This evaluation was distinct from previous studies that considered LLMs as interactive assistants. The primary objective was to assess whether these models could effectively function as independent agents in executing complex cyber-attacks without human intervention.
+
+Our study of Llama 3.1 405B’s social engineering uplift for cyber attackers was conducted to assess the effectiveness of AI models in aiding cyber threat actors in spear phishing campaigns. Please read our Llama 3.1 Cyber security whitepaper to learn more.
+
+
+### Community
+
+Generative AI safety requires expertise and tooling, and we believe in the strength of the open community to accelerate its progress. We are active members of open consortiums, including the AI Alliance, Partnership on AI and MLCommons, actively contributing to safety standardization and transparency. We encourage the community to adopt taxonomies like the MLCommons Proof of Concept evaluation to facilitate collaboration and transparency on safety and content evaluations. Our Purple Llama tools are open sourced for the community to use and widely distributed across ecosystem partners including cloud service providers. We encourage community contributions to our [Github repository](https://github.com/meta-llama/PurpleLlama).
+
+We also set up the [Llama Impact Grants](https://llama.meta.com/llama-impact-grants/) program to identify and support the most compelling applications of Meta’s Llama model for societal benefit across three categories: education, climate and open innovation. The 20 finalists from the hundreds of applications can be found [here](https://llama.meta.com/llama-impact-grants/#finalists).
+
+Finally, we put in place a set of resources including an [output reporting mechanism](https://developers.facebook.com/llama_output_feedback) and [bug bounty program](https://www.facebook.com/whitehat) to continuously improve the Llama technology with the help of the community.
+
+
+## Ethical Considerations and Limitations
+
+The core values of Llama 3.1 are openness, inclusivity and helpfulness. It is meant to serve everyone, and to work for a wide range of use cases. It is thus designed to be accessible to people across many different backgrounds, experiences and perspectives. Llama 3.1 addresses users and their needs as they are, without insertion unnecessary judgment or normativity, while reflecting the understanding that even content that may appear problematic in some cases can serve valuable purposes in others. It respects the dignity and autonomy of all users, especially in terms of the values of free thought and expression that power innovation and progress.
+
+But Llama 3.1 is a new technology, and like any new technology, there are risks associated with its use. Testing conducted to date has not covered, nor could it cover, all scenarios. For these reasons, as with all LLMs, Llama 3.1’s potential outputs cannot be predicted in advance, and the model may in some instances produce inaccurate, biased or other objectionable responses to user prompts. Therefore, before deploying any applications of Llama 3.1 models, developers should perform safety testing and tuning tailored to their specific applications of the model. Please refer to available resources including our [Responsible Use Guide](https://llama.meta.com/responsible-use-guide), [Trust and Safety](https://llama.meta.com/trust-and-safety/) solutions, and other [resources](https://llama.meta.com/docs/get-started/) to learn more about responsible development.
diff --git a/examples/DocQA/example_data/llama_3.2.md b/examples/DocQA/example_data/llama_3.2.md
new file mode 100644
index 000000000..0bc604261
--- /dev/null
+++ b/examples/DocQA/example_data/llama_3.2.md
@@ -0,0 +1,216 @@
+## Model Information
+
+The Llama 3.2 collection of multilingual large language models (LLMs) is a collection of pretrained and instruction-tuned generative models in 1B and 3B sizes (text in/text out). The Llama 3.2 instruction-tuned text only models are optimized for multilingual dialogue use cases, including agentic retrieval and summarization tasks. They outperform many of the available open source and closed chat models on common industry benchmarks.
+
+Model Developer: Meta
+
+Model Architecture: Llama 3.2 is an auto-regressive language model that uses an optimized transformer architecture. The tuned versions use supervised fine-tuning (SFT) and reinforcement learning with human feedback (RLHF) to align with human preferences for helpfulness and safety.
+
+| | Training Data | Params | Input modalities | Output modalities | Context Length | GQA | Shared Embeddings | Token count | Knowledge cutoff |
+| :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |
+| Llama 3.2 (text only) | A new mix of publicly available online data. | 1B (1.23B) | Multilingual Text | Multilingual Text and code | 128k | Yes | Yes | Up to 9T tokens | December 2023 |
+| | | 3B (3.21B) | Multilingual Text | Multilingual Text and code | | | | | |
+| Llama 3.2 Quantized (text only) | A new mix of publicly available online data. | 1B (1.23B) | Multilingual Text | Multilingual Text and code | 8k | Yes | Yes | Up to 9T tokens | December 2023 |
+| | | 3B (3.21B) | Multilingual Text | Multilingual Text and code | | | | | |
+
+Supported Languages: English, German, French, Italian, Portuguese, Hindi, Spanish, and Thai are officially supported. Llama 3.2 has been trained on a broader collection of languages than these 8 supported languages. Developers may fine-tune Llama 3.2 models for languages beyond these supported languages, provided they comply with the Llama 3.2 Community License and the Acceptable Use Policy. Developers are always expected to ensure that their deployments, including those that involve additional languages, are completed safely and responsibly.
+
+Llama 3.2 Model Family: Token counts refer to pretraining data only. All model versions use Grouped-Query Attention (GQA) for improved inference scalability.
+
+Model Release Date: Oct 24, 2024
+
+Status: This is a static model trained on an offline dataset. Future versions may be released that improve model capabilities and safety.
+
+License: Use of Llama 3.2 is governed by the [Llama 3.2 Community License](https://github.com/meta-llama/llama-models/blob/main/models/llama3_2/LICENSE) (a custom, commercial license agreement).
+
+Feedback: Instructions on how to provide feedback or comments on the model can be found in the Llama Models [README](https://github.com/meta-llama/llama-models/blob/main/README.md). For more technical information about generation parameters and recipes for how to use Llama 3.2 in applications, please go [here](https://github.com/meta-llama/llama-recipes).
+
+## Intended Use
+
+Intended Use Cases: Llama 3.2 is intended for commercial and research use in multiple languages. Instruction tuned text only models are intended for assistant-like chat and agentic applications like knowledge retrieval and summarization, mobile AI powered writing assistants and query and prompt rewriting. Pretrained models can be adapted for a variety of additional natural language generation tasks. Similarly, quantized models can be adapted for a variety of on-device use-cases with limited compute resources.
+
+Out of Scope: Use in any manner that violates applicable laws or regulations (including trade compliance laws). Use in any other way that is prohibited by the Acceptable Use Policy and Llama 3.2 Community License. Use in languages beyond those explicitly referenced as supported in this model card.
+
+## Hardware and Software
+
+Training Factors: We used custom training libraries, Meta's custom built GPU cluster, and production infrastructure for pretraining. Fine-tuning, quantization, annotation, and evaluation were also performed on production infrastructure.
+
+Training Energy Use: Training utilized a cumulative of 916k GPU hours of computation on H100-80GB (TDP of 700W) type hardware, per the table below. Training time is the total GPU time required for training each model and power consumption is the peak power capacity per GPU device used, adjusted for power usage efficiency.
+
+Training Greenhouse Gas Emissions: Estimated total location-based greenhouse gas emissions were 240 tons CO2eq for training. Since 2020, Meta has maintained net zero greenhouse gas emissions in its global operations and matched 100% of its electricity use with renewable energy; therefore, the total market-based greenhouse gas emissions for training were 0 tons CO2eq.
+
+| | Training Time (GPU hours) | Logit Generation Time (GPU Hours) | Training Power Consumption (W) | Training Location-Based Greenhouse Gas Emissions (tons CO2eq) | Training Market-Based Greenhouse Gas Emissions (tons CO2eq) |
+| :---- | :---: | ----- | :---: | :---: | :---: |
+| Llama 3.2 1B | 370k | \- | 700 | 107 | 0 |
+| Llama 3.2 3B | 460k | \- | 700 | 133 | 0 |
+| Llama 3.2 1B SpinQuant | 1.7 | 0 | 700 | *Negligible*\*\* | 0 |
+| Llama 3.2 3B SpinQuant | 2.4 | 0 | 700 | *Negligible*\*\* | 0 |
+| Llama 3.2 1B QLoRA | 1.3k | 0 | 700 | 0.381 | 0 |
+| Llama 3.2 3B QLoRA | 1.6k | 0 | 700 | 0.461 | 0 |
+| Total | 833k | 86k | | 240 | 0 |
+
+\*\* The location-based CO2e emissions of Llama 3.2 1B SpinQuant and Llama 3.2 3B SpinQuant are less than 0.001 metric tonnes each. This is due to the minimal training GPU hours that are required.
+
+The methodology used to determine training energy use and greenhouse gas emissions can be found [here](https://arxiv.org/pdf/2204.05149). Since Meta is openly releasing these models, the training energy use and greenhouse gas emissions will not be incurred by others.
+
+## Training Data
+
+Overview: Llama 3.2 was pretrained on up to 9 trillion tokens of data from publicly available sources. For the 1B and 3B Llama 3.2 models, we incorporated logits from the Llama 3.1 8B and 70B models into the pretraining stage of the model development, where outputs (logits) from these larger models were used as token-level targets. Knowledge distillation was used after pruning to recover performance. In post-training we used a similar recipe as Llama 3.1 and produced final chat models by doing several rounds of alignment on top of the pre-trained model. Each round involved Supervised Fine-Tuning (SFT), Rejection Sampling (RS), and Direct Preference Optimization (DPO).
+
+Data Freshness: The pretraining data has a cutoff of December 2023\.
+
+## Quantization
+
+### Quantization Scheme
+
+We designed the current quantization scheme with the [PyTorch’s ExecuTorch](https://github.com/pytorch/executorch) inference framework and Arm CPU backend in mind, taking into account metrics including model quality, prefill/decoding speed, and memory footprint. Our quantization scheme involves three parts:
+- All linear layers in all transformer blocks are quantized to a 4-bit groupwise scheme (with a group size of 32) for weights and 8-bit per-token dynamic quantization for activations.
+- The classification layer is quantized to 8-bit per-channel for weight and 8-bit per token dynamic quantization for activation.
+- Similar to classification layer, an 8-bit per channel quantization is used for embedding layer.
+
+
+### Quantization-Aware Training and LoRA
+
+The quantization-aware training (QAT) with low-rank adaptation (LoRA) models went through only post-training stages, using the same data as the full precision models. To initialize QAT, we utilize BF16 Llama 3.2 model checkpoints obtained after supervised fine-tuning (SFT) and perform an additional full round of SFT training with QAT. We used the [torchao](https://github.com/pytorch/ao/blob/main/torchao/quantization/qat/README.md) API for this. We then freeze the backbone of the QAT model and perform another round of SFT with LoRA adaptors applied to all layers within the transformer block. Meanwhile, the LoRA adaptors' weights and activations are maintained in BF16. Because our approach is similar to QLoRA of Dettmers et al., (2023) (i.e., quantization followed by LoRA adapters), we refer this method as QLoRA. Finally, we fine-tune the resulting model (both backbone and LoRA adaptors) using direct preference optimization (DPO).
+
+### SpinQuant
+
+[SpinQuant](https://arxiv.org/abs/2405.16406) was applied, together with generative post-training quantization (GPTQ). For the SpinQuant rotation matrix fine-tuning, we optimized for 100 iterations, using 800 samples with sequence-length 2048 from the WikiText 2 dataset. For GPTQ, we used 128 samples from the same dataset with the same sequence-length.
+
+## Benchmarks \- English Text
+
+In this section, we report the results for Llama 3.2 models on standard automatic benchmarks. For all these evaluations, we used our internal evaluations library.
+
+### Base Pretrained Models
+
+| Category | Benchmark | \# Shots | Metric | Llama 3.2 1B | Llama 3.2 3B | Llama 3.1 8B |
+| ----- | ----- | :---: | :---: | :---: | :---: | :---: |
+| General | MMLU | 5 | macro\_avg/acc\_char | 32.2 | 58 | 66.7 |
+| | AGIEval English | 3-5 | average/acc\_char | 23.3 | 39.2 | 47.8 |
+| | ARC-Challenge | 25 | acc\_char | 32.8 | 69.1 | 79.7 |
+| Reading comprehension | SQuAD | 1 | em | 49.2 | 67.7 | 77 |
+| | QuAC (F1) | 1 | f1 | 37.9 | 42.9 | 44.9 |
+| | DROP (F1) | 3 | f1 | 28.0 | 45.2 | 59.5 |
+| Long Context | Needle in Haystack | 0 | em | 96.8 | 1 | 1 |
+
+### Instruction Tuned Models
+
+| Capability | | Benchmark | \# Shots | Metric | Llama 3.2 1B bf16 | Llama 3.2 1B Vanilla PTQ\*\* | Llama 3.2 1B Spin Quant | Llama 3.2 1B QLoRA | Llama 3.2 3B bf16 | Llama 3.2 3B Vanilla PTQ\*\* | Llama 3.2 3B Spin Quant | Llama 3.2 3B QLoRA | Llama 3.1 8B |
+| :---: | ----- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| General | | MMLU | 5 | macro\_avg/acc | 49.3 | 43.3 | 47.3 | 49.0 | 63.4 | 60.5 | 62 | 62.4 | 69.4 |
+| Re-writing | | Open-rewrite eval | 0 | micro\_avg/rougeL | 41.6 | 39.2 | 40.9 | 41.2 | 40.1 | 40.3 | 40.8 | 40.7 | 40.9 |
+| Summarization | | TLDR9+ (test) | 1 | rougeL | 16.8 | 14.9 | 16.7 | 16.8 | 19.0 | 19.1 | 19.2 | 19.1 | 17.2 |
+| Instruction following | | IFEval | 0 | Avg(Prompt/Instruction acc Loose/Strict) | 59.5 | 51.5 | 58.4 | 55.6 | 77.4 | 73.9 | 73.5 | 75.9 | 80.4 |
+| Math | | GSM8K (CoT) | 8 | em\_maj1@1 | 44.4 | 33.1 | 40.6 | 46.5 | 77.7 | 72.9 | 75.7 | 77.9 | 84.5 |
+| | | MATH (CoT) | 0 | final\_em | 30.6 | 20.5 | 25.3 | 31.0 | 48.0 | 44.2 | 45.3 | 49.2 | 51.9 |
+| Reasoning | | ARC-C | 0 | acc | 59.4 | 54.3 | 57 | 60.7 | 78.6 | 75.6 | 77.6 | 77.6 | 83.4 |
+| | | GPQA | 0 | acc | 27.2 | 25.9 | 26.3 | 25.9 | 32.8 | 32.8 | 31.7 | 33.9 | 32.8 |
+| | | Hellaswag | 0 | acc | 41.2 | 38.1 | 41.3 | 41.5 | 69.8 | 66.3 | 68 | 66.3 | 78.7 |
+| Tool Use | | BFCL V2 | 0 | acc | 25.7 | 14.3 | 15.9 | 23.7 | 67.0 | 53.4 | 60.1 | 63.5 | 67.1 |
+| | | Nexus | 0 | macro\_avg/acc | 13.5 | 5.2 | 9.6 | 12.5 | 34.3 | 32.4 | 31.5 | 30.1 | 38.5 |
+| Long Context | | InfiniteBench/En.QA | 0 | longbook\_qa/f1 | 20.3 | N/A | N/A | N/A | 19.8 | N/A | N/A | N/A | 27.3 |
+| | | InfiniteBench/En.MC | 0 | longbook\_choice/acc | 38.0 | N/A | N/A | N/A | 63.3 | N/A | N/A | N/A | 72.2 |
+| | | NIH/Multi-needle | 0 | recall | 75.0 | N/A | N/A | N/A | 84.7 | N/A | N/A | N/A | 98.8 |
+| Multilingual | | MGSM (CoT) | 0 | em | 24.5 | 13.7 | 18.2 | 24.4 | 58.2 | 48.9 | 54.3 | 56.8 | 68.9 |
+
+\*\*for comparison purposes only. Model not released.
+
+### Multilingual Benchmarks
+
+| Category | Benchmark | Language | Llama 3.2 1B | Llama 3.2 1B Vanilla PTQ\*\* | Llama 3.2 1B Spin Quant | Llama 3.2 1B QLoRA | Llama 3.2 3B | Llama 3.2 3B Vanilla PTQ\*\* | Llama 3.2 3B Spin Quant | Llama 3.2 3B QLoRA | Llama 3.1 8B |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| General | MMLU (5-shot, macro_avg/acc) | Portuguese | 39.8 | 34.9 | 38.9 | 40.2 | 54.5 | 50.9 | 53.3 | 53.4 | 62.1 |
+| | | Spanish | 41.5 | 36.0 | 39.8 | 41.8 | 55.1 | 51.9 | 53.6 | 53.6 | 62.5 |
+| | | Italian | 39.8 | 34.9 | 38.1 | 40.6 | 53.8 | 49.9 | 52.1 | 51.7 | 61.6 |
+| | | German | 39.2 | 34.9 | 37.5 | 39.6 | 53.3 | 50.0 | 52.2 | 51.3 | 60.6 |
+| | | French | 40.5 | 34.8 | 39.2 | 40.8 | 54.6 | 51.2 | 53.3 | 53.3 | 62.3 |
+| | | Hindi | 33.5 | 30.0 | 32.1 | 34.0 | 43.3 | 40.4 | 42.0 | 42.1 | 50.9 |
+| | | Thai | 34.7 | 31.2 | 32.4 | 34.9 | 44.5 | 41.3 | 44.0 | 42.2 | 50.3 |
+
+\*\*for comparison purposes only. Model not released.
+
+## Inference time
+
+In the below table, we compare the performance metrics of different quantization methods (SpinQuant and QAT \+ LoRA) with the BF16 baseline. The evaluation was done using the [ExecuTorch](https://github.com/pytorch/executorch) framework as the inference engine, with the ARM CPU as a backend using Android OnePlus 12 device.
+
+| Category | Decode (tokens/sec) | Time-to-first-token (sec) | Prefill (tokens/sec) | Model size (PTE file size in MB) | Memory size (RSS in MB) |
+| :---- | ----- | ----- | ----- | ----- | ----- |
+| 1B BF16 (baseline) | 19.2 | 1.0 | 60.3 | 2358 | 3,185 |
+| 1B SpinQuant | 50.2 (2.6x) | 0.3 (-76.9%) | 260.5 (4.3x) | 1083 (-54.1%) | 1,921 (-39.7%) |
+| 1B QLoRA | 45.8 (2.4x) | 0.3 (-76.0%) | 252.0 (4.2x) | 1127 (-52.2%) | 2,255 (-29.2%) |
+| 3B BF16 (baseline) | 7.6 | 3.0 | 21.2 | 6129 | 7,419 |
+| 3B SpinQuant | 19.7 (2.6x) | 0.7 (-76.4%) | 89.7 (4.2x) | 2435 (-60.3%) | 3,726 (-49.8%) |
+| 3B QLoRA | 18.5 (2.4x) | 0.7 (-76.1%) | 88.8 (4.2x) | 2529 (-58.7%) | 4,060 (-45.3%) |
+
+(\*) The performance measurement is done using an adb binary-based approach.
+(\*\*) It is measured on an Android OnePlus 12 device.
+(\*\*\*) Time-to-first-token (TTFT) is measured with prompt length=64
+
+*Footnote:*
+
+- *Decode (tokens/second) is for how quickly it keeps generating. Higher is better.*
+- *Time-to-first-token (TTFT for shorthand) is for how fast it generates the first token for a given prompt. Lower is better.*
+- *Prefill is the inverse of TTFT (aka 1/TTFT) in tokens/second. Higher is better*
+- *Model size \- how big is the model, measured by, PTE file, a binary file format for ExecuTorch*
+- *RSS size \- Memory usage in resident set size (RSS)*
+
+## Responsibility & Safety
+
+As part of our Responsible release approach, we followed a three-pronged strategy to managing trust & safety risks:
+
+1. Enable developers to deploy helpful, safe and flexible experiences for their target audience and for the use cases supported by Llama
+2. Protect developers against adversarial users aiming to exploit Llama capabilities to potentially cause harm
+3. Provide protections for the community to help prevent the misuse of our models
+
+### Responsible Deployment
+
+Approach: Llama is a foundational technology designed to be used in a variety of use cases. Examples on how Meta’s Llama models have been responsibly deployed can be found in our [Community Stories webpage](https://llama.meta.com/community-stories/). Our approach is to build the most helpful models, enabling the world to benefit from the technology power, by aligning our model safety for generic use cases and addressing a standard set of harms. Developers are then in the driver’s seat to tailor safety for their use cases, defining their own policies and deploying the models with the necessary safeguards in their Llama systems. Llama 3.2 was developed following the best practices outlined in our [Responsible Use Guide](https://llama.meta.com/responsible-use-guide/).
+
+#### Llama 3.2 Instruct
+
+Objective: Our main objectives for conducting safety fine-tuning are to provide the research community with a valuable resource for studying the robustness of safety fine-tuning, as well as to offer developers a readily available, safe, and powerful model for various applications to reduce the developer workload to deploy safe AI systems. We implemented the same set of safety mitigations as in Llama 3, and you can learn more about these in the Llama 3 [paper](https://ai.meta.com/research/publications/the-llama-3-herd-of-models/).
+
+Fine-Tuning Data: We employ a multi-faceted approach to data collection, combining human-generated data from our vendors with synthetic data to mitigate potential safety risks. We’ve developed many large language model (LLM)-based classifiers that enable us to thoughtfully select high-quality prompts and responses, enhancing data quality control.
+
+Refusals and Tone: Building on the work we started with Llama 3, we put a great emphasis on model refusals to benign prompts as well as refusal tone. We included both borderline and adversarial prompts in our safety data strategy, and modified our safety data responses to follow tone guidelines.
+
+#### Llama 3.2 Systems
+
+Safety as a System: Large language models, including Llama 3.2, are not designed to be deployed in isolation but instead should be deployed as part of an overall AI system with additional safety guardrails as required. Developers are expected to deploy system safeguards when building agentic systems. Safeguards are key to achieve the right helpfulness-safety alignment as well as mitigating safety and security risks inherent to the system and any integration of the model or system with external tools. As part of our responsible release approach, we provide the community with [safeguards](https://llama.meta.com/trust-and-safety/) that developers should deploy with Llama models or other LLMs, including Llama Guard, Prompt Guard and Code Shield. All our [reference implementations](https://github.com/meta-llama/llama-agentic-system) demos contain these safeguards by default so developers can benefit from system-level safety out-of-the-box.
+
+### New Capabilities and Use Cases
+
+Technological Advancement: Llama releases usually introduce new capabilities that require specific considerations in addition to the best practices that generally apply across all Generative AI use cases. For prior release capabilities also supported by Llama 3.2, see [Llama 3.1 Model Card](https://github.com/meta-llama/llama-models/blob/main/models/llama3_1/MODEL_CARD.md), as the same considerations apply here as well.
+
+Constrained Environments: Llama 3.2 1B and 3B models are expected to be deployed in highly constrained environments, such as mobile devices. LLM Systems using smaller models will have a different alignment profile and safety/helpfulness tradeoff than more complex, larger systems. Developers should ensure the safety of their system meets the requirements of their use case. We recommend using lighter system safeguards for such use cases, like Llama Guard 3-1B or its mobile-optimized version.
+
+### Evaluations
+
+Scaled Evaluations: We built dedicated, adversarial evaluation datasets and evaluated systems composed of Llama models and Purple Llama safeguards to filter input prompt and output response. It is important to evaluate applications in context, and we recommend building dedicated evaluation dataset for your use case.
+
+Red Teaming: We conducted recurring red teaming exercises with the goal of discovering risks via adversarial prompting and we used the learnings to improve our benchmarks and safety tuning datasets. We partnered early with subject-matter experts in critical risk areas to understand the nature of these real-world harms and how such models may lead to unintended harm for society. Based on these conversations, we derived a set of adversarial goals for the red team to attempt to achieve, such as extracting harmful information or reprogramming the model to act in a potentially harmful capacity. The red team consisted of experts in cybersecurity, adversarial machine learning, responsible AI, and integrity in addition to multilingual content specialists with background in integrity issues in specific geographic markets.
+
+### Critical Risks
+
+In addition to our safety work above, we took extra care on measuring and/or mitigating the following critical risk areas:
+
+1\. CBRNE (Chemical, Biological, Radiological, Nuclear, and Explosive Weapons): Llama 3.2 1B and 3B models are smaller and less capable derivatives of Llama 3.1. For Llama 3.1 70B and 405B, to assess risks related to proliferation of chemical and biological weapons, we performed uplift testing designed to assess whether use of Llama 3.1 models could meaningfully increase the capabilities of malicious actors to plan or carry out attacks using these types of weapons and have determined that such testing also applies to the smaller 1B and 3B models.
+
+2\. Child Safety: Child Safety risk assessments were conducted using a team of experts, to assess the model’s capability to produce outputs that could result in Child Safety risks and inform on any necessary and appropriate risk mitigations via fine tuning. We leveraged those expert red teaming sessions to expand the coverage of our evaluation benchmarks through Llama 3 model development. For Llama 3, we conducted new in-depth sessions using objective based methodologies to assess the model risks along multiple attack vectors including the additional languages Llama 3 is trained on. We also partnered with content specialists to perform red teaming exercises assessing potentially violating content while taking account of market specific nuances or experiences.
+
+3\. Cyber Attacks: For Llama 3.1 405B, our cyber attack uplift study investigated whether LLMs can enhance human capabilities in hacking tasks, both in terms of skill level and speed.
+Our attack automation study focused on evaluating the capabilities of LLMs when used as autonomous agents in cyber offensive operations, specifically in the context of ransomware attacks. This evaluation was distinct from previous studies that considered LLMs as interactive assistants. The primary objective was to assess whether these models could effectively function as independent agents in executing complex cyber-attacks without human intervention. Because Llama 3.2’s 1B and 3B models are smaller and less capable models than Llama 3.1 405B, we broadly believe that the testing conducted for the 405B model also applies to Llama 3.2 models.
+
+### Community
+
+Industry Partnerships: Generative AI safety requires expertise and tooling, and we believe in the strength of the open community to accelerate its progress. We are active members of open consortiums, including the AI Alliance, Partnership on AI and MLCommons, actively contributing to safety standardization and transparency. We encourage the community to adopt taxonomies like the MLCommons Proof of Concept evaluation to facilitate collaboration and transparency on safety and content evaluations. Our Purple Llama tools are open sourced for the community to use and widely distributed across ecosystem partners including cloud service providers. We encourage community contributions to our [Github repository](https://github.com/meta-llama/PurpleLlama).
+
+Grants: We also set up the [Llama Impact Grants](https://llama.meta.com/llama-impact-grants/) program to identify and support the most compelling applications of Meta’s Llama model for societal benefit across three categories: education, climate and open innovation. The 20 finalists from the hundreds of applications can be found [here](https://llama.meta.com/llama-impact-grants/#finalists).
+
+Reporting: Finally, we put in place a set of resources including an [output reporting mechanism](https://developers.facebook.com/llama_output_feedback) and [bug bounty program](https://www.facebook.com/whitehat) to continuously improve the Llama technology with the help of the community.
+
+## Ethical Considerations and Limitations
+
+Values: The core values of Llama 3.2 are openness, inclusivity and helpfulness. It is meant to serve everyone, and to work for a wide range of use cases. It is thus designed to be accessible to people across many different backgrounds, experiences and perspectives. Llama 3.2 addresses users and their needs as they are, without insertion unnecessary judgment or normativity, while reflecting the understanding that even content that may appear problematic in some cases can serve valuable purposes in others. It respects the dignity and autonomy of all users, especially in terms of the values of free thought and expression that power innovation and progress.
+
+Testing: Llama 3.2 is a new technology, and like any new technology, there are risks associated with its use. Testing conducted to date has not covered, nor could it cover, all scenarios. For these reasons, as with all LLMs, Llama 3.2’s potential outputs cannot be predicted in advance, and the model may in some instances produce inaccurate, biased or other objectionable responses to user prompts. Therefore, before deploying any applications of Llama 3.2 models, developers should perform safety testing and tuning tailored to their specific applications of the model. Please refer to available resources including our [Responsible Use Guide](https://llama.meta.com/responsible-use-guide), [Trust and Safety](https://llama.meta.com/trust-and-safety/) solutions, and other [resources](https://llama.meta.com/docs/get-started/) to learn more about responsible development.
diff --git a/examples/DocQA/example_data/llama_3.2_vision.md b/examples/DocQA/example_data/llama_3.2_vision.md
new file mode 100644
index 000000000..e64eee2d1
--- /dev/null
+++ b/examples/DocQA/example_data/llama_3.2_vision.md
@@ -0,0 +1,160 @@
+## Model Information
+
+The Llama 3.2-Vision collection of multimodal large language models (LLMs) is a collection of pretrained and instruction-tuned image reasoning generative models in 11B and 90B sizes (text \+ images in / text out). The Llama 3.2-Vision instruction-tuned models are optimized for visual recognition, image reasoning, captioning, and answering general questions about an image. The models outperform many of the available open source and closed multimodal models on common industry benchmarks.
+
+Model Developer: Meta
+
+Model Architecture: Llama 3.2-Vision is built on top of the Llama 3.1 text-only model, which is an auto-regressive language model that uses an optimized transformer architecture. The tuned versions use supervised fine-tuning (SFT) and reinforcement learning with human feedback (RLHF) to align with human preferences for helpfulness and safety. To support image recognition tasks, the Llama 3.2-Vision model uses a separately trained vision adapter that integrates with the pre-trained Llama 3.1 language model. The adapter consists of a series of cross-attention layers that feed image encoder representations into the core LLM.
+
+| | Training Data | Params | Input modalities | Output modalities | Context length | GQA | Data volume | Knowledge cutoff |
+| :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |
+| Llama 3.2-Vision | (Image, text) pairs | 11B (10.6) | Text \+ Image | Text | 128k | Yes | 6B (image, text) pairs | December 2023 |
+| Llama 3.2-Vision | (Image, text) pairs | 90B (88.8) | Text \+ Image | Text | 128k | Yes | 6B (image, text) pairs | December 2023 |
+
+Supported Languages: For text only tasks, English, German, French, Italian, Portuguese, Hindi, Spanish, and Thai are officially supported. Llama 3.2 has been trained on a broader collection of languages than these 8 supported languages. Note for image+text applications, English is the only language supported.
+
+Developers may fine-tune Llama 3.2 models for languages beyond these supported languages, provided they comply with the Llama 3.2 Community License and the Acceptable Use Policy. Developers are always expected to ensure that their deployments, including those that involve additional languages, are completed safely and responsibly.
+
+Llama 3.2 Model Family: Token counts refer to pretraining data only. All model versions use Grouped-Query Attention (GQA) for improved inference scalability.
+
+Model Release Date: Sept 25, 2024
+
+Status: This is a static model trained on an offline dataset. Future versions may be released that improve model capabilities and safety.
+
+License: Use of Llama 3.2 is governed by the [Llama 3.2 Community License](https://github.com/meta-llama/llama-models/blob/main/models/llama3_2/LICENSE) (a custom, commercial license agreement).
+
+Feedback: Instructions on how to provide feedback or comments on the model can be found in the Llama Models [README](https://github.com/meta-llama/llama-models/blob/main/README.md). For more technical information about generation parameters and recipes for how to use Llama 3.2-Vision in applications, please go [here](https://github.com/meta-llama/llama-recipes).
+
+## Intended Use
+
+Intended Use Cases: Llama 3.2-Vision is intended for commercial and research use. Instruction tuned models are intended for visual recognition, image reasoning, captioning, and assistant-like chat with images, whereas pretrained models can be adapted for a variety of image reasoning tasks. Additionally, because of Llama 3.2-Vision’s ability to take images and text as inputs, additional use cases could include:
+
+1. Visual Question Answering (VQA) and Visual Reasoning: Imagine a machine that looks at a picture and understands your questions about it.
+2. Document Visual Question Answering (DocVQA): Imagine a computer understanding both the text and layout of a document, like a map or contract, and then answering questions about it directly from the image.
+3. Image Captioning: Image captioning bridges the gap between vision and language, extracting details, understanding the scene, and then crafting a sentence or two that tells the story.
+4. Image-Text Retrieval: Image-text retrieval is like a matchmaker for images and their descriptions. Similar to a search engine but one that understands both pictures and words.
+5. Visual Grounding: Visual grounding is like connecting the dots between what we see and say. It’s about understanding how language references specific parts of an image, allowing AI models to pinpoint objects or regions based on natural language descriptions.
+
+
+The Llama 3.2 model collection also supports the ability to leverage the outputs of its models to improve other models including synthetic data generation and distillation. The Llama 3.2 Community License allows for these use cases.
+
+Out of Scope: Use in any manner that violates applicable laws or regulations (including trade compliance laws). Use in any other way that is prohibited by the Acceptable Use Policy and Llama 3.2 Community License. Use in languages beyond those explicitly referenced as supported in this model card.
+
+## Hardware and Software
+
+Training Factors: We used custom training libraries, Meta's custom built GPU cluster, and production infrastructure for pretraining. Fine-tuning, annotation, and evaluation were also performed on production infrastructure.
+
+Training Energy Use: Training utilized a cumulative of 2.02M GPU hours of computation on H100-80GB (TDP of 700W) type hardware, per the table below. Training time is the total GPU time required for training each model and power consumption is the peak power capacity per GPU device used, adjusted for power usage efficiency.
+
+##
+
+Training Greenhouse Gas Emissions: Estimated total location-based greenhouse gas emissions were 584 tons CO2eq for training. Since 2020, Meta has maintained net zero greenhouse gas emissions in its global operations and matched 100% of its electricity use with renewable energy, therefore the total market-based greenhouse gas emissions for training were 0 tons CO2eq.
+
+| | Training Time (GPU hours) | Training Power Consumption (W) | Training Location-Based Greenhouse Gas Emissions (tons CO2eq) | Training Market-Based Greenhouse Gas Emissions (tons CO2eq) |
+| :---- | :---: | :---: | :---: | :---: |
+| Llama 3.2-vision 11B | Stage 1 pretraining: 147K H100 hours Stage 2 annealing: 98K H100 hours SFT: 896 H100 hours RLHF: 224 H100 hours | 700 | 71 | 0 |
+| Llama 3.2-vision 90B | Stage 1 pretraining: 885K H100 hours Stage 2 annealing: 885K H100 hours SFT: 3072 H100 hours RLHF: 2048 H100 hours | 700 | 513 | 0 |
+| Total | 2.02M | | 584 | 0 |
+
+The methodology used to determine training energy use and greenhouse gas emissions can be found [here](https://arxiv.org/pdf/2204.05149). Since Meta is openly releasing these models, the training energy use and greenhouse gas emissions will not be incurred by others.
+
+## Training Data
+
+Overview: Llama 3.2-Vision was pretrained on 6B image and text pairs. The instruction tuning data includes publicly available vision instruction datasets, as well as over 3M synthetically generated examples.
+
+Data Freshness: The pretraining data has a cutoff of December 2023\.
+
+## Benchmarks \- Image Reasoning
+
+In this section, we report the results for Llama 3.2-Vision models on standard automatic benchmarks. For all these evaluations, we used our internal evaluations library.
+
+### Base Pretrained Models
+
+| Category | Benchmark | \# Shots | Metric | Llama 3.2 11B | Llama 3.2 90B |
+| ----- | ----- | ----- | ----- | ----- | ----- |
+| Image Understanding | VQAv2 (val) | 0 | Accuracy | 66.8 | 73.6 |
+| | Text VQA (val) | 0 | Relaxed accuracy | 73.1 | 73.5 |
+| | DocVQA (val, unseen) | 0 | ANLS | 62.3 | 70.7 |
+| Visual Reasoning | MMMU (val, 0-shot) | 0 | Micro average accuracy | 41.7 | 49.3 |
+| | ChartQA (test) | 0 | Accuracy | 39.4 | 54.2 |
+| | InfographicsQA (val, unseen) | 0 | ANLS | 43.2 | 56.8 |
+| | AI2 Diagram (test) | 0 | Accuracy | 62.4 | 75.3 |
+
+### Instruction Tuned Models
+
+| Modality | Capability | Benchmark | \# Shots | Metric | Llama 3.2 11B | Llama 3.2 90B |
+| ----- | :---: | ----- | :---: | :---: | ----- | ----- |
+| Image | College-level Problems and Mathematical Reasoning | MMMU (val, CoT) | 0 | Micro average accuracy | 50.7 | 60.3 |
+| | | MMMU-Pro, Standard (10 opts, test) | 0 | Accuracy | 33.0 | 45.2 |
+| | | MMMU-Pro, Vision (test) | 0 | Accuracy | 23.7 | 33.8 |
+| | | MathVista (testmini) | 0 | Accuracy | 51.5 | 57.3 |
+| | Charts and Diagram Understanding | ChartQA (test, CoT) | 0 | Relaxed accuracy | 83.4 | 85.5 |
+| | | AI2 Diagram (test) | 0 | Accuracy | 91.1 | 92.3 |
+| | | DocVQA (test) | 0 | ANLS | 88.4 | 90.1 |
+| | General Visual Question Answering | VQAv2 (test) | 0 | Accuracy | 75.2 | 78.1 |
+| | | | | | | |
+| Text | General | MMLU (CoT) | 0 | Macro\_avg/acc | 73.0 | 86.0 |
+| | Math | MATH (CoT) | 0 | Final\_em | 51.9 | 68.0 |
+| | Reasoning | GPQA | 0 | Accuracy | 32.8 | 46.7 |
+| | Multilingual | MGSM (CoT) | 0 | em | 68.9 | 86.9 |
+
+## Responsibility & Safety
+
+As part of our Responsible release approach, we followed a three-pronged strategy to managing trust & safety risks:
+
+1. Enable developers to deploy helpful, safe and flexible experiences for their target audience and for the use cases supported by Llama.
+2. Protect developers against adversarial users aiming to exploit Llama capabilities to potentially cause harm.
+3. Provide protections for the community to help prevent the misuse of our models.
+
+### Responsible Deployment
+
+Approach: Llama is a foundational technology designed to be used in a variety of use cases, examples on how Meta’s Llama models have been responsibly deployed can be found in our [Community Stories webpage](https://llama.meta.com/community-stories/). Our approach is to build the most helpful models enabling the world to benefit from the technology power, by aligning our model safety for the generic use cases addressing a standard set of harms. Developers are then in the driver seat to tailor safety for their use case, defining their own policy and deploying the models with the necessary safeguards in their Llama systems. Llama 3.2 was developed following the best practices outlined in our Responsible Use Guide, you can refer to the [Responsible Use Guide](https://llama.meta.com/responsible-use-guide/) to learn more.
+
+#### Llama 3.2 Instruct
+
+Objective: Our main objectives for conducting safety fine-tuning are to provide the research community with a valuable resource for studying the robustness of safety fine-tuning, as well as to offer developers a readily available, safe, and powerful model for various applications to reduce the developer workload to deploy safe AI systems. We implemented the same set of safety mitigations as in Llama 3, and you can learn more about these in the Llama 3 [paper](https://ai.meta.com/research/publications/the-llama-3-herd-of-models/).
+
+Fine-Tuning Data: We employ a multi-faceted approach to data collection, combining human-generated data from our vendors with synthetic data to mitigate potential safety risks. We’ve developed many large language model (LLM)-based classifiers that enable us to thoughtfully select high-quality prompts and responses, enhancing data quality control.
+
+Refusals and Tone: Building on the work we started with Llama 3, we put a great emphasis on model refusals to benign prompts as well as refusal tone. We included both borderline and adversarial prompts in our safety data strategy, and modified our safety data responses to follow tone guidelines.
+
+#### Llama 3.2 Systems
+
+Safety as a System: Large language models, including Llama 3.2, are not designed to be deployed in isolation but instead should be deployed as part of an overall AI system with additional safety guardrails as required. Developers are expected to deploy system safeguards when building agentic systems. Safeguards are key to achieve the right helpfulness-safety alignment as well as mitigating safety and security risks inherent to the system and any integration of the model or system with external tools. As part of our responsible release approach, we provide the community with [safeguards](https://llama.meta.com/trust-and-safety/) that developers should deploy with Llama models or other LLMs, including Llama Guard, Prompt Guard and Code Shield. All our [reference implementations](https://github.com/meta-llama/llama-agentic-system) demos contain these safeguards by default so developers can benefit from system-level safety out-of-the-box.
+
+### New Capabilities and Use Cases
+
+Technological Advancement: Llama releases usually introduce new capabilities that require specific considerations in addition to the best practices that generally apply across all Generative AI use cases. For prior release capabilities also supported by Llama 3.2, see [Llama 3.1 Model Card](https://github.com/meta-llama/llama-models/blob/main/models/llama3_1/MODEL_CARD.md), as the same considerations apply here as well.
+
+Image Reasoning: Llama 3.2-Vision models come with multimodal (text and image) input capabilities enabling image reasoning applications. As part of our responsible release process, we took dedicated measures including evaluations and mitigations to address the risk of the models uniquely identifying individuals in images. As with other LLM risks, models may not always be robust to adversarial prompts, and developers should evaluate identification and other applicable risks in the context of their applications as well as consider deploying Llama Guard 3-11B-Vision as part of their system or other mitigations as appropriate to detect and mitigate such risks.
+
+### Evaluations
+
+Scaled Evaluations: We built dedicated, adversarial evaluation datasets and evaluated systems composed of Llama models and Purple Llama safeguards to filter input prompt and output response. It is important to evaluate applications in context, and we recommend building dedicated evaluation dataset for your use case.
+
+Red teaming: We conducted recurring red teaming exercises with the goal of discovering risks via adversarial prompting and we used the learnings to improve our benchmarks and safety tuning datasets. We partnered early with subject-matter experts in critical risk areas to understand the nature of these real-world harms and how such models may lead to unintended harm for society. Based on these conversations, we derived a set of adversarial goals for the red team to attempt to achieve, such as extracting harmful information or reprogramming the model to act in a potentially harmful capacity. The red team consisted of experts in cybersecurity, adversarial machine learning, responsible AI, and integrity in addition to multilingual content specialists with background in integrity issues in specific geographic markets.
+
+### Critical Risks
+
+In addition to our safety work above, we took extra care on measuring and/or mitigating the following critical risk areas:
+
+1\. CBRNE (Chemical, Biological, Radiological, Nuclear, and Explosive Weapons): For Llama 3.1, to assess risks related to proliferation of chemical and biological weapons, we performed uplift testing designed to assess whether use of Llama 3.1 models could meaningfully increase the capabilities of malicious actors to plan or carry out attacks using these types of weapons. For Llama 3.2-Vision models, we conducted additional targeted evaluations and found that it was unlikely Llama 3.2 presented an increase in scientific capabilities due to its added image understanding capability as compared to Llama 3.1.
+
+2\. Child Safety: Child Safety risk assessments were conducted using a team of experts, to assess the model’s capability to produce outputs that could result in Child Safety risks and inform on any necessary and appropriate risk mitigations via fine tuning. We leveraged those expert red teaming sessions to expand the coverage of our evaluation benchmarks through Llama 3 model development. For Llama 3, we conducted new in-depth sessions using objective based methodologies to assess the model risks along multiple attack vectors including the additional languages Llama 3 is trained on. We also partnered with content specialists to perform red teaming exercises assessing potentially violating content while taking account of market specific nuances or experiences.
+
+3\. Cyber Attacks: For Llama 3.1 405B, our cyber attack uplift study investigated whether LLMs can enhance human capabilities in hacking tasks, both in terms of skill level and speed.
+Our attack automation study focused on evaluating the capabilities of LLMs when used as autonomous agents in cyber offensive operations, specifically in the context of ransomware attacks. This evaluation was distinct from previous studies that considered LLMs as interactive assistants. The primary objective was to assess whether these models could effectively function as independent agents in executing complex cyber-attacks without human intervention. Because Llama 3.2’s vision capabilities are not generally germane to cyber uplift, we believe that the testing conducted for Llama 3.1 also applies to Llama 3.2.
+
+### Community
+
+Industry Partnerships: Generative AI safety requires expertise and tooling, and we believe in the strength of the open community to accelerate its progress. We are active members of open consortiums, including the AI Alliance, Partnership on AI and MLCommons, actively contributing to safety standardization and transparency. We encourage the community to adopt taxonomies like the MLCommons Proof of Concept evaluation to facilitate collaboration and transparency on safety and content evaluations. Our Purple Llama tools are open sourced for the community to use and widely distributed across ecosystem partners including cloud service providers. We encourage community contributions to our [Github repository](https://github.com/meta-llama/PurpleLlama).
+
+Grants: We also set up the [Llama Impact Grants](https://llama.meta.com/llama-impact-grants/) program to identify and support the most compelling applications of Meta’s Llama model for societal benefit across three categories: education, climate and open innovation. The 20 finalists from the hundreds of applications can be found [here](https://llama.meta.com/llama-impact-grants/#finalists).
+
+Reporting: Finally, we put in place a set of resources including an [output reporting mechanism](https://developers.facebook.com/llama_output_feedback) and [bug bounty program](https://www.facebook.com/whitehat) to continuously improve the Llama technology with the help of the community.
+
+## Ethical Considerations and Limitations
+
+Values: The core values of Llama 3.2 are openness, inclusivity and helpfulness. It is meant to serve everyone, and to work for a wide range of use cases. It is thus designed to be accessible to people across many different backgrounds, experiences and perspectives. Llama 3.2 addresses users and their needs as they are, without insertion unnecessary judgment or normativity, while reflecting the understanding that even content that may appear problematic in some cases can serve valuable purposes in others. It respects the dignity and autonomy of all users, especially in terms of the values of free thought and expression that power innovation and progress.
+
+Testing: But Llama 3.2 is a new technology, and like any new technology, there are risks associated with its use. Testing conducted to date has not covered, nor could it cover, all scenarios. For these reasons, as with all LLMs, Llama 3.2’s potential outputs cannot be predicted in advance, and the model may in some instances produce inaccurate, biased or other objectionable responses to user prompts. Therefore, before deploying any applications of Llama 3.2 models, developers should perform safety testing and tuning tailored to their specific applications of the model. Please refer to available resources including our [Responsible Use Guide](https://llama.meta.com/responsible-use-guide), [Trust and Safety](https://llama.meta.com/trust-and-safety/) solutions, and other [resources](https://llama.meta.com/docs/get-started/) to learn more about responsible development.
diff --git a/examples/DocQA/requirements.txt b/examples/DocQA/requirements.txt
new file mode 100644
index 000000000..d680aa671
--- /dev/null
+++ b/examples/DocQA/requirements.txt
@@ -0,0 +1,5 @@
+llama-stack==0.0.57
+lxml>=4.9.0,<5.0.0
+xmltodict>=0.12.0,<1.0.0
+pycryptodomex>=3.8.2,<4.0.0
+google-cloud-storage>=1.16,<2.0
\ No newline at end of file
diff --git a/examples/DocQA/scripts/caption_outputs.py b/examples/DocQA/scripts/caption_outputs.py
new file mode 100644
index 000000000..8ab5cdf01
--- /dev/null
+++ b/examples/DocQA/scripts/caption_outputs.py
@@ -0,0 +1,127 @@
+import os
+import asyncio
+import argparse
+import base64
+import mimetypes
+from pathlib import Path
+from llama_stack_client import LlamaStackClient
+from llama_stack_client.lib.inference.event_logger import EventLogger
+
+def parse_args():
+ parser = argparse.ArgumentParser(description='Process document images with LlamaStack Vision API')
+ parser.add_argument('--host', type=str, default='localhost', help='LlamaStack server host (default: localhost)')
+ parser.add_argument('--port', type=int, default=5000, help='LlamaStack server port (default: 5000)')
+ parser.add_argument('--input_dir', type=str, required=True, help='Input directory containing markdown files and images')
+ return parser.parse_args()
+
+def encode_image_to_data_url(file_path: str) -> str:
+ """Encode an image file to a data URL."""
+ mime_type, _ = mimetypes.guess_type(file_path)
+ if mime_type is None:
+ raise ValueError("Could not determine MIME type of the file")
+
+ with open(file_path, "rb") as image_file:
+ encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
+
+ return f"data:{mime_type};base64,{encoded_string}"
+
+class DocumentProcessor:
+ def __init__(self, host: str, port: int):
+ self.client = LlamaStackClient(base_url=f"http://{host}:{port}")
+ self.processed_images = {}
+
+ async def get_image_caption(self, image_path: str) -> str:
+ """Get caption for an image using LlamaStack Vision API."""
+ if image_path in self.processed_images:
+ return self.processed_images[image_path]
+
+ try:
+ data_url = encode_image_to_data_url(image_path)
+
+ message = {
+ "role": "user",
+ "content": [
+ {"image": {"uri": data_url}},
+ "This image comes from a scan inside a document, please provide a high level caption of what you see inside the image."
+ ]
+ }
+
+ response = await self.client.inference.chat_completion(
+ messages=[message],
+ model="Llama3.2-11B-Vision-Instruct",
+ stream=False
+ )
+
+ caption = response.choices[0].message.content
+ self.processed_images[image_path] = caption
+ return caption
+
+ except Exception as e:
+ print(f"Error processing image {image_path}: {str(e)}")
+ return None
+
+ async def process_markdown_file(self, output_dir: str, md_filename: str) -> None:
+ """Process a single markdown file and replace image placeholders with captions."""
+ print(f"Processing: {md_filename}")
+
+ md_path = Path(output_dir) / md_filename
+ images_dir = Path(output_dir) / 'images'
+
+ try:
+ content = md_path.read_text(encoding='utf-8')
+ except Exception as e:
+ print(f"Failed to read {md_filename}: {str(e)}")
+ return
+
+ base_name = md_filename.rsplit('.', 1)[0]
+ image_count = 1
+ updated = False
+
+ while '' in content:
+ image_filename = f"{base_name}-figure-{image_count}.png"
+ image_path = images_dir / image_filename
+
+ if not image_path.exists():
+ print(f"Image not found: {image_filename}")
+ break
+
+ caption = await self.get_image_caption(str(image_path))
+ if caption:
+ image_markdown = f"\n\n_{caption}_"
+ content = content.replace('', image_markdown, 1)
+ print(f"Processed image {image_count} for {base_name}")
+ updated = True
+ else:
+ print(f"Failed to process image {image_filename}")
+ break
+
+ image_count += 1
+
+ if updated:
+ try:
+ md_path.write_text(content, encoding='utf-8')
+ except Exception as e:
+ print(f"Failed to write updated content to {md_filename}: {str(e)}")
+
+async def main():
+ args = parse_args()
+ output_dir = Path(args.input_dir)
+
+ if not output_dir.exists():
+ print(f"Input directory not found: {output_dir}")
+ return
+
+ processor = DocumentProcessor(host=args.host, port=args.port)
+ md_files = list(output_dir.glob('*.md'))
+
+ if not md_files:
+ print(f"No markdown files found in {output_dir}")
+ return
+
+ for md_file in md_files:
+ await processor.process_markdown_file(output_dir, md_file.name)
+
+ print("Processing completed")
+
+if __name__ == "__main__":
+ asyncio.run(main())
diff --git a/examples/DocQA/scripts/ingest_files.py b/examples/DocQA/scripts/ingest_files.py
new file mode 100644
index 000000000..89252d987
--- /dev/null
+++ b/examples/DocQA/scripts/ingest_files.py
@@ -0,0 +1,182 @@
+import argparse
+import json
+import logging
+import shutil
+from pathlib import Path
+from typing import List, Tuple
+
+import yaml
+import os
+
+from docling.backend.pypdfium2_backend import PyPdfiumDocumentBackend
+from docling.datamodel.base_models import InputFormat
+from docling.datamodel.document import PictureItem, TableItem
+from docling.datamodel.pipeline_options import PdfPipelineOptions
+from docling.document_converter import (
+ DocumentConverter,
+ PdfFormatOption,
+ WordFormatOption,
+)
+from docling.pipeline.simple_pipeline import SimplePipeline
+from docling.pipeline.standard_pdf_pipeline import StandardPdfPipeline
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ description="Process documents from input directory"
+ )
+ parser.add_argument(
+ "--input_dir",
+ type=str,
+ required=True,
+ help="Input directory containing documents",
+ )
+ parser.add_argument(
+ "--output_dir",
+ type=str,
+ help="Output directory for processed files (default: input_dir/output)",
+ )
+ return parser.parse_args()
+
+
+def get_document_files(input_dir: Path) -> Tuple[List[Path], List[Path]]:
+ """
+ Recursively scan directory for document files.
+ Returns:
+ tuple: (documents_to_process, markdown_files)
+ """
+ process_extensions = {".pdf", ".docx", ".pptx"}
+ documents_to_process = []
+ markdown_files = []
+
+ for path in input_dir.rglob("*"):
+ if path.is_file():
+ if path.suffix.lower() in process_extensions:
+ documents_to_process.append(path)
+ elif path.suffix.lower() == ".md":
+ markdown_files.append(path)
+
+ return documents_to_process, markdown_files
+
+
+def save_images(res, output_subdir: Path, doc_filename: str) -> List[Tuple[str, Path]]:
+ """
+ Extracts and saves images from the document.
+ Returns a list of (image_type, image_path) tuples for future processing.
+ """
+ images_dir = output_subdir / "images"
+ images_dir.mkdir(parents=True, exist_ok=True)
+ saved_images = []
+
+ # Save page images
+ for page_no, page in res.document.pages.items():
+ if hasattr(page, "image") and page.image:
+ image_path = images_dir / f"{doc_filename}-page-{page_no}.png"
+ with image_path.open("wb") as fp:
+ page.image.pil_image.save(fp, format="PNG")
+ saved_images.append(("page", image_path))
+
+ # Save images of figures and tables
+ table_counter = 0
+ picture_counter = 0
+
+ for element, _level in res.document.iterate_items():
+ if (
+ isinstance(element, TableItem)
+ and hasattr(element, "image")
+ and element.image
+ ):
+ table_counter += 1
+ image_path = images_dir / f"{doc_filename}-table-{table_counter}.png"
+ with image_path.open("wb") as fp:
+ element.image.pil_image.save(fp, "PNG")
+ saved_images.append(("table", image_path))
+
+ if (
+ isinstance(element, PictureItem)
+ and hasattr(element, "image")
+ and element.image
+ ):
+ picture_counter += 1
+ image_path = images_dir / f"{doc_filename}-figure-{picture_counter}.png"
+ with image_path.open("wb") as fp:
+ element.image.pil_image.save(fp, "PNG")
+ saved_images.append(("figure", image_path))
+
+ return saved_images
+
+
+def main():
+ args = parse_args()
+
+ # Set up input and output directories
+ input_dir = Path(args.input_dir)
+ output_dir = Path(args.output_dir) if args.output_dir else input_dir / "output"
+ if os.path.exists(output_dir):
+ print(f"Output directory already exists: {output_dir}, will stop ingestion")
+ raise Exception(f"Output directory already exists: {output_dir}")
+ else:
+ output_dir.mkdir(parents=True, exist_ok=True)
+
+ # Get all document files recursively
+ documents_to_process, markdown_files = get_document_files(input_dir)
+
+ # Copy markdown files directly
+ for md_file in markdown_files:
+ relative_path = md_file.relative_to(input_dir)
+ output_path = output_dir / relative_path
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copy2(md_file, output_path)
+ print(f"Copied: {md_file}")
+
+ if documents_to_process:
+ # Configure pipeline options
+ pipeline_options = PdfPipelineOptions()
+ pipeline_options.do_ocr = False
+ pipeline_options.images_scale = 2.0
+ pipeline_options.generate_page_images = False
+ pipeline_options.generate_table_images = False
+ pipeline_options.generate_picture_images = True
+
+ # Configure document converter
+ doc_converter = DocumentConverter(
+ allowed_formats=[
+ InputFormat.PDF,
+ InputFormat.DOCX,
+ InputFormat.PPTX,
+ ],
+ format_options={
+ InputFormat.PDF: PdfFormatOption(
+ pipeline_cls=StandardPdfPipeline,
+ backend=PyPdfiumDocumentBackend,
+ pipeline_options=pipeline_options,
+ ),
+ InputFormat.DOCX: WordFormatOption(pipeline_cls=SimplePipeline),
+ },
+ )
+
+ # Process all documents
+ conv_results = doc_converter.convert_all(documents_to_process)
+ all_extracted_images = []
+
+ # Save results
+ for res in conv_results:
+ relative_path = res.input.file.relative_to(input_dir)
+ output_subdir = output_dir / relative_path.parent
+ output_subdir.mkdir(parents=True, exist_ok=True)
+
+ md_path = output_subdir / f"{res.input.file.stem}.md"
+
+ print(f"Converting: {res.input.file}" f"\nSaving to: {md_path}")
+
+ extracted_images = save_images(res, output_subdir, res.input.file.stem)
+ all_extracted_images.extend(extracted_images)
+
+ with md_path.open("w", encoding="utf-8") as fp:
+ fp.write(res.document.export_to_markdown())
+
+ print(f"\nExtracted {len(all_extracted_images)} images in total")
+ print("Ready for image captioning processing")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/agents/rag_with_memory_bank.py b/examples/agents/rag_with_memory_bank.py
index 76f82884e..1dde56d19 100644
--- a/examples/agents/rag_with_memory_bank.py
+++ b/examples/agents/rag_with_memory_bank.py
@@ -36,22 +36,15 @@ async def run_main(host: str, port: int, disable_safety: bool = False):
client = LlamaStackClient(base_url=f"http://{host}:{port}")
providers = client.providers.list()
-
- available_shields = [shield.identifier for shield in client.shields.list()]
- if not available_shields:
- print("No available shields. Disable safety.")
- else:
- print(f"Available shields found: {available_shields}")
-
# create a memory bank
client.memory_banks.register(
- memory_bank_id="test_bank",
- params={
+ memory_bank={
+ "identifier": "test_bank",
"embedding_model": "all-MiniLM-L6-v2",
"chunk_size_in_tokens": 512,
"overlap_size_in_tokens": 64,
- },
- provider_id=providers["memory"][0].provider_id,
+ "provider_id": providers["memory"][0].provider_id,
+ }
)
# insert some documents
@@ -67,7 +60,7 @@ async def run_main(host: str, port: int, disable_safety: bool = False):
print(f"Using model: {selected_model}")
agent_config = AgentConfig(
- model=selected_model,
+ model="Llama3.1-8B-Instruct",
instructions="You are a helpful assistant",
sampling_params={
"strategy": "greedy",
@@ -121,4 +114,4 @@ def main(host: str, port: int):
if __name__ == "__main__":
- fire.Fire(main)
+ fire.Fire(main)
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 90082937a..f84ea4bee 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,5 @@
-fastapi
fire
-httpx
mesop
python-dotenv
setuptools
-uvicorn
yfinance
-gradio
-llama-stack>=0.0.57
-llama-stack-client>=0.0.57