Skip to content

Commit 88241d0

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents beb6a31 + dd23862 commit 88241d0

File tree

4 files changed

+57
-243
lines changed

4 files changed

+57
-243
lines changed

examples/kfto_feast_rag/README.md

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ This example notebook provides a step-by-step demonstration of building and usin
2020

2121
4. RAG System Implementation
2222
- **Embedding Model**: `all-MiniLM-L6-v2` (configurable)
23-
- **Generator Model**: `granite-3.2-2b-instruct` (configurable)
24-
- **Vector Store**: Custom implementation with Feast integration
25-
- **Retriever**: Custom implementation with Feast integration extending HuggingFace's RagRetriever
23+
- **Generator Model**: `granite-3.2-2b-instruct` (configurable)
24+
- **Vector Store**: Feast’s built-in FeastVectorStore backed by Milvus
25+
- **Retriever**: Feast’s native RAG retriever FeastRAGRetriever
2626

2727
5. Query Demonstration
2828
- Perform inference with retrieved context
@@ -37,17 +37,6 @@ This example notebook provides a step-by-step demonstration of building and usin
3737
From the workbench, clone this repository: https://github.com/opendatahub-io/distributed-workloads.git
3838
Navigate to the distributed-workloads/examples/kfto-feast-rag directory. Here you will find the following files:
3939

40-
* **feast_rag_retriever.py**
41-
This module implements a custom RAG retriever by combining Feast feature store capabilities with HuggingFace transformer-based models. The implementation provides:
42-
43-
- A flexible vector store interface with Feast integration (`FeastVectorStore`)
44-
- A custom RAG retriever (`FeastRAGRetriever`) that supports three search modes:
45-
- Text-based search
46-
- Vector-based search
47-
- Hybrid search
48-
- Seamless integration with HuggingFace transformers library and sentence-transformers
49-
- Configurable document formatting and retrieval options
50-
5140
* **feature_repo/feature_store.yaml**
5241
This is the core configuration file for the RAG project's feature store, configuring a Milvus online store on a local provider.
5342
* In order to configure Milvus you should:
@@ -56,7 +45,7 @@ Navigate to the distributed-workloads/examples/kfto-feast-rag directory. Here yo
5645
- port (default: 19530)
5746
- credentials (if required)
5847

59-
* **__feature_repo/rag_project_repo.py__**
48+
* **__feature_repo/ragproject_repo.py__**
6049
This is the Feast feature repository configuration that defines the schema and data source for Wikipedia passage embeddings.
6150

6251
* **__rag_feast_kfto.ipynb__**

examples/kfto_feast_rag/feast_rag_retriever.py

Lines changed: 0 additions & 204 deletions
This file was deleted.

examples/kfto_feast_rag/feature_repo/feature_store.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ provider: local
33
registry: data/registry.db
44
online_store:
55
type: milvus
6-
host: # Insert Milvus route host
6+
host: http:// # Insert Milvus route host
77
username: # Insert Milvus username if required
88
password: # Insert Milvus password if required
99
port: 19530

examples/kfto_feast_rag/rag_feast_kfto.ipynb

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
"metadata": {},
2121
"outputs": [],
2222
"source": [
23-
"# Note: `faiss-cpu` is included here due to an assumption in the Hugging Face `RagRetriever` class\n",
24-
"# that the FAISS library is required, even though it's not directly used in this example.\n",
25-
"%pip install --quiet feast[milvus] sentence-transformers datasets faiss-cpu\n",
23+
"%pip install --quiet feast[milvus] sentence-transformers datasets\n",
2624
"%pip install bigtree==0.19.2\n",
2725
"%pip install marshmallow==3.10.0 "
2826
]
@@ -51,31 +49,50 @@
5149
")"
5250
]
5351
},
52+
{
53+
"cell_type": "markdown",
54+
"metadata": {},
55+
"source": [
56+
"The dataset is chunked to contain a preset number of chars, which is the max supported by Feast. Ensuring the chunk only contains whole words, thus the retrieved context can form sentences without incomplete words."
57+
]
58+
},
5459
{
5560
"cell_type": "code",
5661
"execution_count": null,
5762
"metadata": {},
5863
"outputs": [],
5964
"source": [
60-
"def chunk_dataset(examples, chunk_size=100, overlap=20, max_chars=500):\n",
65+
"def chunk_dataset(examples, max_chars=380):\n",
6166
" all_chunks = []\n",
6267
" all_ids = []\n",
6368
" all_titles = []\n",
6469
"\n",
65-
" for i, text in enumerate(examples['text']): # Iterate over texts in the batch\n",
70+
" for i, text in enumerate(examples['text']): # Iterate over texts in the batch\n",
6671
" words = text.split()\n",
67-
" chunks = []\n",
68-
" for j in range(0, len(words), chunk_size - overlap):\n",
69-
" chunk_words = words[j:j + chunk_size]\n",
70-
" if len(chunk_words) < 20:\n",
71-
" continue\n",
72-
" chunk_text_value = ' '.join(chunk_words) # Store the chunk text\n",
73-
" chunk_text_value = chunk_text_value[:max_chars]\n",
74-
" chunks.append(chunk_text_value)\n",
75-
" all_ids.append(f\"{examples['id'][i]}_{j}\") # Unique ID for the chunk\n",
76-
" all_titles.append(examples['title'][i])\n",
72+
" if not words:\n",
73+
" continue\n",
7774
"\n",
78-
" all_chunks.extend(chunks)\n",
75+
" current_chunk_words = []\n",
76+
" for word in words:\n",
77+
" # Check if adding the next word exceeds the character limit\n",
78+
" if len(' '.join(current_chunk_words + [word])) > max_chars:\n",
79+
" # If the current chunk is valid, save it\n",
80+
" if current_chunk_words:\n",
81+
" chunk_text = ' '.join(current_chunk_words)\n",
82+
" all_chunks.append(chunk_text)\n",
83+
" all_ids.append(f\"{examples['id'][i]}_{len(all_chunks)}\") # Unique ID for the chunk\n",
84+
" all_titles.append(examples['title'][i])\n",
85+
" # Start a new chunk with the current word\n",
86+
" current_chunk_words = [word]\n",
87+
" else:\n",
88+
" current_chunk_words.append(word)\n",
89+
"\n",
90+
" # Add the last remaining chunk\n",
91+
" if current_chunk_words:\n",
92+
" chunk_text = ' '.join(current_chunk_words)\n",
93+
" all_chunks.append(chunk_text)\n",
94+
" all_ids.append(f\"{examples['id'][i]}_{len(all_chunks)}\") # Unique ID for the chunk\n",
95+
" all_titles.append(examples['title'][i])\n",
7996
"\n",
8097
" return {'id': all_ids, 'title': all_titles, 'text': all_chunks}\n",
8198
"\n",
@@ -120,6 +137,15 @@
120137
"#### Create parquet file as historical data source"
121138
]
122139
},
140+
{
141+
"cell_type": "code",
142+
"execution_count": null,
143+
"metadata": {},
144+
"outputs": [],
145+
"source": [
146+
"%mkdir feature_repo/data"
147+
]
148+
},
123149
{
124150
"cell_type": "code",
125151
"execution_count": null,
@@ -145,7 +171,7 @@
145171
"print(df[\"embedding\"].apply(lambda x: len(x) if isinstance(x, list) else str(type(x))).value_counts()) # Check lengths\n",
146172
"\n",
147173
"# Save to Parquet\n",
148-
"df.to_parquet(\"wiki_dpr.parquet\", index=False)\n",
174+
"df.to_parquet(\"feature_repo/data/wiki_dpr.parquet\", index=False)\n",
149175
"print(\"Saved to wiki_dpr.parquet\")"
150176
]
151177
},
@@ -231,8 +257,9 @@
231257
"source": [
232258
"import sys\n",
233259
"sys.path.append(\"..\")\n",
234-
"from feast_rag_retriever import FeastVectorStore, FeastRAGRetriever, FeastIndex\n",
235-
"from rag_project_repo import wiki_passage_feature_view\n",
260+
"from ragproject_repo import wiki_passage_feature_view\n",
261+
"from feast.vector_store import FeastVectorStore\n",
262+
"from feast.rag_retriever import FeastIndex, FeastRAGRetriever\n",
236263
"\n",
237264
"generator_config=generator_model.config\n",
238265
"question_encoder = AutoModel.from_pretrained(\"sentence-transformers/all-MiniLM-L6-v2\")\n",
@@ -245,12 +272,12 @@
245272
"}\n",
246273
"\n",
247274
"vector_store = FeastVectorStore(\n",
248-
" store=store,\n",
275+
" repo_path=\".\",\n",
249276
" rag_view=wiki_passage_feature_view,\n",
250-
" features=[\"wiki_passages:passage_text\", \"wiki_passages:embedding\"]\n",
277+
" features=[\"wiki_passages:passage_text\", \"wiki_passages:embedding\", \"wiki_passages:passage_id\"]\n",
251278
")\n",
252279
"\n",
253-
"feast_index = FeastIndex(vector_store=vector_store)\n",
280+
"feast_index = FeastIndex()\n",
254281
"\n",
255282
"config = RagConfig(\n",
256283
" question_encoder=query_encoder_config,\n",
@@ -262,10 +289,12 @@
262289
" question_encoder_tokenizer=question_encoder_tokenizer,\n",
263290
" generator_tokenizer=generator_tokenizer,\n",
264291
" feast_repo_path=\".\",\n",
265-
" vector_store=vector_store,\n",
292+
" feature_view=vector_store.rag_view,\n",
293+
" features=vector_store.features,\n",
266294
" generator_model=generator_model, \n",
267295
" search_type=\"vector\",\n",
268296
" id_field=\"passage_id\",\n",
297+
" text_field=\"passage_text\",\n",
269298
" config=config,\n",
270299
" index=feast_index,\n",
271300
")"

0 commit comments

Comments
 (0)