Skip to content

Commit a142e8d

Browse files
committed
Merge commit '97726fb4fe459515088cb1b01bf01b0b116dabe7'
Conflicts: docs/source/user_guide/large_language_model/index.rst
2 parents d622542 + 97726fb commit a142e8d

File tree

3 files changed

+201
-8
lines changed

3 files changed

+201
-8
lines changed

ads/llm/serializers/retrieval_qa.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def load(config: dict, **kwargs):
3030
os.environ.get("OCI_OPENSEARCH_PASSWORD", None),
3131
),
3232
verify_certs=True
33-
if os.environ.get("OCI_OPENSEARCH_VERIFY_CERTS", None).lower() == "true"
33+
if os.environ.get("OCI_OPENSEARCH_VERIFY_CERTS", None) == "True"
3434
else False,
3535
ca_certs=os.environ.get("OCI_OPENSEARCH_CA_CERTS", None),
3636
)
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
.. _vector_store:
2+
3+
########################
4+
Vector Store integration
5+
########################
6+
7+
.. versionadded:: 2.9.1
8+
9+
Current version of Langchain does not support serialization of any vector stores. This will be a problem when you want to deploy a langchain application with the vector store being one of the components using data science model deployment service. To solve this problem, we extended our support of vector stores serialization:
10+
11+
- ``OpenSearchVectorSearch``
12+
- ``FAISS``
13+
14+
OpenSearchVectorSearch Serialization
15+
------------------------------------
16+
17+
langchain does not automatically support serialization of ``OpenSearchVectorSearch``. However, ADS provides a way to serialize ``OpenSearchVectorSearch``. To serialize ``OpenSearchVectorSearch``, you need to use environment variables to pass in the credentials. The following variables can be passed in through the corresponding environment variables:
18+
19+
- http_auth: (``OCI_OPENSEARCH_USERNAME``, ``OCI_OPENSEARCH_PASSWORD``)
20+
- verify_certs: ``OCI_OPENSEARCH_VERIFY_CERTS``
21+
- ca_certs: ``OCI_OPENSEARCH_CA_CERTS``
22+
23+
The following code snippet shows how to use ``OpenSearchVectorSearch`` with environment variables:
24+
25+
.. code-block:: python3
26+
27+
os.environ['OCI_OPENSEARCH_USERNAME'] = "username"
28+
os.environ['OCI_OPENSEARCH_PASSWORD'] = "password"
29+
os.environ['OCI_OPENSEARCH_VERIFY_CERTS'] = "False"
30+
31+
INDEX_NAME = "your_index_name"
32+
opensearch_vector_search = OpenSearchVectorSearch(
33+
"https://localhost:9200",
34+
embedding_function=oci_embedings,
35+
index_name=INDEX_NAME,
36+
engine="lucene",
37+
http_auth=(os.environ["OCI_OPENSEARCH_USERNAME"], os.environ["OCI_OPENSEARCH_PASSWORD"]),
38+
verify_certs=os.environ["OCI_OPENSEARCH_VERIFY_CERTS"],
39+
)
40+
41+
.. admonition:: Deployment
42+
:class: note
43+
44+
During deployment, it is very important that you remember to pass in those environment variables as well:
45+
46+
.. code-block:: python3
47+
48+
.deploy(deployment_log_group_id="ocid1.loggroup.####",
49+
deployment_access_log_id="ocid1.log.####",
50+
deployment_predict_log_id="ocid1.log.####",
51+
environment_variables={"OCI_OPENSEARCH_USERNAME":"<oci_opensearch_username>",
52+
"OCI_OPENSEARCH_PASSWORD": "<oci_opensearch_password>",
53+
"OCI_OPENSEARCH_VERIFY_CERTS": "<oci_opensearch_verify_certs>",)
54+
55+
OpenSearchVectorSearch Deployment
56+
---------------------------------
57+
58+
Here is an example code snippet for OpenSearchVectorSearch deployment:
59+
60+
.. code-block:: python3
61+
62+
from langchain.vectorstores import OpenSearchVectorSearch
63+
from ads.llm import GenerativeAIEmbeddings, GenerativeAI
64+
import ads
65+
66+
ads.set_auth("resource_principal")
67+
68+
oci_embedings = GenerativeAIEmbeddings(
69+
compartment_id="ocid1.compartment.oc1..aaaaaaaapvb3hearqum6wjvlcpzm5ptfxqa7xfftpth4h72xx46ygavkqteq",
70+
client_kwargs=dict(service_endpoint="https://generativeai.aiservice.us-chicago-1.oci.oraclecloud.com") # this can be omitted after Generative AI service is GA.
71+
)
72+
73+
oci_llm = GenerativeAI(
74+
compartment_id="ocid1.compartment.oc1..aaaaaaaapvb3hearqum6wjvlcpzm5ptfxqa7xfftpth4h72xx46ygavkqteq",
75+
client_kwargs=dict(service_endpoint="https://generativeai.aiservice.us-chicago-1.oci.oraclecloud.com") # this can be omitted after Generative AI service is GA.
76+
)
77+
78+
import os
79+
os.environ['OCI_OPENSEARCH_USERNAME'] = "username"
80+
os.environ['OCI_OPENSEARCH_PASSWORD'] = "password"
81+
os.environ['OCI_OPENSEARCH_VERIFY_CERTS'] = "True" # make sure this is capitalized.
82+
os.environ['OCI_OPENSEARCH_CA_CERTS'] = "path/to/oci_opensearch_ca.pem"
83+
84+
INDEX_NAME = "your_index_name"
85+
opensearch_vector_search = OpenSearchVectorSearch(
86+
"https://localhost:9200", # your endpoint
87+
embedding_function=oci_embedings,
88+
index_name=INDEX_NAME,
89+
engine="lucene",
90+
http_auth=(os.environ["OCI_OPENSEARCH_USERNAME"], os.environ["OCI_OPENSEARCH_PASSWORD"]),
91+
verify_certs=os.environ["OCI_OPENSEARCH_VERIFY_CERTS"],
92+
ca_certs=os.environ["OCI_OPENSEARCH_CA_CERTS"],
93+
)
94+
from langchain.chains import RetrievalQA
95+
retriever = opensearch_vector_search.as_retriever(search_kwargs={"vector_field": "embeds",
96+
"text_field": "text",
97+
"k": 3,
98+
"size": 3},
99+
max_tokens_limit=1000)
100+
qa = RetrievalQA.from_chain_type(
101+
llm=oci_llm,
102+
chain_type="stuff",
103+
retriever=retriever,
104+
chain_type_kwargs={
105+
"verbose": True
106+
}
107+
)
108+
from ads.llm.deploy import ChainDeployment
109+
model = ChainDeployment(qa)
110+
model.prepare(force_overwrite=True,
111+
inference_conda_env="your_conda_pack",
112+
)
113+
114+
model.save()
115+
res = model.verify("your prompt")
116+
model.deploy(deployment_log_group_id="ocid1.loggroup.####",
117+
deployment_access_log_id="ocid1.log.####",
118+
deployment_predict_log_id="ocid1.log.####",
119+
environment_variables={"OCI_OPENSEARCH_USERNAME":"<oci_opensearch_username>",
120+
"OCI_OPENSEARCH_PASSWORD": "<oci_opensearch_password>",
121+
"OCI_OPENSEARCH_VERIFY_CERTS": "<oci_opensearch_verify_certs>",
122+
"OCI_OPENSEARCH_CA_CERTS": "<oci_opensearch_ca_certs>"},)
123+
124+
model.predict("your prompt")
125+
126+
127+
FAISS Serialization
128+
-------------------
129+
130+
If your documents are not too large and you dont have a OCI OpenSearch cluster, you can use ``FAISS`` as your in-memory vector store, which can also do similarty search very efficiently. For ``FAISS``, you can just use it and deploy it as it is.
131+
132+
133+
FAISS Deployment
134+
----------------
135+
136+
Here is an example code snippet for FAISS deployment:
137+
138+
.. code-block:: python3
139+
140+
import ads
141+
from ads.llm import GenerativeAIEmbeddings, GenerativeAI
142+
from langchain.document_loaders import TextLoader
143+
from langchain.text_splitter import CharacterTextSplitter
144+
from langchain.vectorstores import FAISS
145+
from langchain.chains import RetrievalQA
146+
147+
ads.set_auth("resource_principal")
148+
oci_embedings = GenerativeAIEmbeddings(
149+
compartment_id="ocid1.compartment.####",
150+
client_kwargs=dict(service_endpoint="https://generativeai.aiservice.us-chicago-1.oci.oraclecloud.com") # this can be omitted after Generative AI service is GA.
151+
)
152+
153+
oci_llm = GenerativeAI(
154+
compartment_id="ocid1.compartment.####",
155+
client_kwargs=dict(service_endpoint="https://generativeai.aiservice.us-chicago-1.oci.oraclecloud.com") # this can be omitted after Generative AI service is GA.
156+
)
157+
158+
loader = TextLoader("your.txt")
159+
documents = loader.load()
160+
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
161+
docs = text_splitter.split_documents(documents)
162+
163+
l = len(docs)
164+
embeddings = []
165+
for i in range(l // 16 + 1):
166+
subdocs = [item.page_content for item in docs[i * 16: (i + 1) * 16]]
167+
embeddings.extend(oci_embedings.embed_documents(subdocs))
168+
169+
texts = [item.page_content for item in docs]
170+
text_embedding_pairs = [(text, embed) for text, embed in zip(texts, embeddings)]
171+
db = FAISS.from_embeddings(text_embedding_pairs, oci_embedings)
172+
173+
retriever = db.as_retriever()
174+
qa = RetrievalQA.from_chain_type(
175+
llm=oci_llm,
176+
chain_type="stuff",
177+
retriever=retriever,
178+
chain_type_kwargs={
179+
"verbose": True
180+
}
181+
)
182+
183+
from ads.llm.deploy import ChainDeployment
184+
model.prepare(force_overwrite=True,
185+
inference_conda_env="your_conda_pack",
186+
)
187+
188+
model.save()
189+
res = model.verify("your prompt")
190+
model.deploy(deployment_log_group_id="ocid1.loggroup.####",
191+
deployment_access_log_id="ocid1.log.####",
192+
deployment_predict_log_id="ocid1.log.####")
193+
194+
model.predict("your prompt")

tests/unitary/with_extras/langchain/test_serialization.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def setUp(self) -> None:
7575
"prompt": {
7676
"lc": 1,
7777
"type": "constructor",
78-
"id": ["langchain", "prompts", "prompt", "PromptTemplate"],
78+
"id": ["langchain_core", "prompts", "prompt", "PromptTemplate"],
7979
"kwargs": {
8080
"input_variables": ["subject"],
8181
"template": "Tell me a joke about {subject}",
@@ -118,21 +118,20 @@ def setUp(self) -> None:
118118
EXPECTED_RUNNABLE_SEQUENCE = {
119119
"lc": 1,
120120
"type": "constructor",
121-
"id": ["langchain", "schema", "runnable", "RunnableSequence"],
121+
"id": ["langchain_core", "runnables", "RunnableSequence"],
122122
"kwargs": {
123123
"first": {
124124
"lc": 1,
125125
"type": "constructor",
126-
"id": ["langchain", "schema", "runnable", "RunnableParallel"],
126+
"id": ["langchain_core", "runnables", "RunnableParallel"],
127127
"kwargs": {
128128
"steps": {
129129
"text": {
130130
"lc": 1,
131131
"type": "constructor",
132132
"id": [
133-
"langchain",
134-
"schema",
135-
"runnable",
133+
"langchain_core",
134+
"runnables",
136135
"RunnablePassthrough",
137136
],
138137
"kwargs": {"func": None, "afunc": None, "input_type": None},
@@ -145,7 +144,7 @@ def setUp(self) -> None:
145144
{
146145
"lc": 1,
147146
"type": "constructor",
148-
"id": ["langchain", "prompts", "prompt", "PromptTemplate"],
147+
"id": ["langchain_core", "prompts", "prompt", "PromptTemplate"],
149148
"kwargs": {
150149
"input_variables": ["subject"],
151150
"template": "Tell me a joke about {subject}",

0 commit comments

Comments
 (0)