Skip to content

Commit 2fddbd3

Browse files
committed
Change text-embedding-3
1 parent e4d98ac commit 2fddbd3

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

app/backend/approaches/approach.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ class Document:
4444
reranker_score: Optional[float] = None
4545

4646
def serialize_for_results(self) -> dict[str, Any]:
47-
return {
47+
result_dict = {
4848
"id": self.id,
4949
"content": self.content,
50-
"embedding": Document.trim_embedding(self.embedding),
5150
"imageEmbedding": Document.trim_embedding(self.image_embedding),
5251
"category": self.category,
5352
"sourcepage": self.sourcepage,
@@ -69,6 +68,8 @@ def serialize_for_results(self) -> dict[str, Any]:
6968
"score": self.score,
7069
"reranker_score": self.reranker_score,
7170
}
71+
result_dict[self.embedding_field] = Document.trim_embedding(self.embedding)
72+
return result_dict
7273

7374
@classmethod
7475
def trim_embedding(cls, embedding: Optional[List[float]]) -> Optional[str]:
@@ -102,6 +103,7 @@ def __init__(
102103
embedding_deployment: Optional[str], # Not needed for non-Azure OpenAI or for retrieval_mode="text"
103104
embedding_model: str,
104105
embedding_dimensions: int,
106+
embedding_field: str,
105107
openai_host: str,
106108
vision_endpoint: str,
107109
vision_token_provider: Callable[[], Awaitable[str]],
@@ -115,6 +117,7 @@ def __init__(
115117
self.embedding_deployment = embedding_deployment
116118
self.embedding_model = embedding_model
117119
self.embedding_dimensions = embedding_dimensions
120+
self.embedding_field = embedding_field
118121
self.openai_host = openai_host
119122
self.vision_endpoint = vision_endpoint
120123
self.vision_token_provider = vision_token_provider
@@ -178,7 +181,7 @@ async def search(
178181
Document(
179182
id=document.get("id"),
180183
content=document.get("content"),
181-
embedding=document.get("embedding"),
184+
embedding=document.get(self.embedding_field),
182185
image_embedding=document.get("imageEmbedding"),
183186
category=document.get("category"),
184187
sourcepage=document.get("sourcepage"),
@@ -254,7 +257,8 @@ class ExtraArgs(TypedDict, total=False):
254257
**dimensions_args,
255258
)
256259
query_vector = embedding.data[0].embedding
257-
return VectorizedQuery(vector=query_vector, k_nearest_neighbors=50, fields="embedding")
260+
# TODO: use optimizations from rag time journey 3
261+
return VectorizedQuery(vector=query_vector, k_nearest_neighbors=50, fields=self.embedding)
258262

259263
async def compute_image_embedding(self, q: str):
260264
endpoint = urljoin(self.vision_endpoint, "computervision/retrieval:vectorizeText")

app/backend/approaches/chatreadretrievereadvision.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def __init__(
3838
embedding_deployment: Optional[str], # Not needed for non-Azure OpenAI or for retrieval_mode="text"
3939
embedding_model: str,
4040
embedding_dimensions: int,
41+
embedding_field: str,
4142
sourcepage_field: str,
4243
content_field: str,
4344
query_language: str,
@@ -57,6 +58,7 @@ def __init__(
5758
self.embedding_deployment = embedding_deployment
5859
self.embedding_model = embedding_model
5960
self.embedding_dimensions = embedding_dimensions
61+
self.embedding_field = embedding_field
6062
self.sourcepage_field = sourcepage_field
6163
self.content_field = content_field
6264
self.query_language = query_language
@@ -86,7 +88,7 @@ async def run_until_final_call(
8688
minimum_reranker_score = overrides.get("minimum_reranker_score", 0.0)
8789
filter = self.build_filter(overrides, auth_claims)
8890

89-
vector_fields = overrides.get("vector_fields", ["embedding"])
91+
vector_fields = overrides.get("vector_fields", [self.embedding_field])
9092
send_text_to_gptvision = overrides.get("gpt4v_input") in ["textAndImages", "texts", None]
9193
send_images_to_gptvision = overrides.get("gpt4v_input") in ["textAndImages", "images", None]
9294

@@ -121,9 +123,9 @@ async def run_until_final_call(
121123
if use_vector_search:
122124
for field in vector_fields:
123125
vector = (
124-
await self.compute_text_embedding(query_text)
125-
if field == "embedding"
126-
else await self.compute_image_embedding(query_text)
126+
await self.compute_image_embedding(query_text)
127+
if field.startswith("image")
128+
else await self.compute_text_embedding(query_text)
127129
)
128130
vectors.append(vector)
129131

app/backend/approaches/retrievethenreadvision.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(
3232
embedding_deployment: Optional[str], # Not needed for non-Azure OpenAI or for retrieval_mode="text"
3333
embedding_model: str,
3434
embedding_dimensions: int,
35+
embedding_field: str,
3536
sourcepage_field: str,
3637
content_field: str,
3738
query_language: str,
@@ -47,6 +48,7 @@ def __init__(
4748
self.embedding_model = embedding_model
4849
self.embedding_deployment = embedding_deployment
4950
self.embedding_dimensions = embedding_dimensions
51+
self.embedding_field = embedding_field
5052
self.sourcepage_field = sourcepage_field
5153
self.content_field = content_field
5254
self.gpt4v_deployment = gpt4v_deployment
@@ -81,7 +83,7 @@ async def run(
8183
minimum_reranker_score = overrides.get("minimum_reranker_score", 0.0)
8284
filter = self.build_filter(overrides, auth_claims)
8385

84-
vector_fields = overrides.get("vector_fields", ["embedding"])
86+
vector_fields = overrides.get("vector_fields", [self.embedding_field])
8587
send_text_to_gptvision = overrides.get("gpt4v_input") in ["textAndImages", "texts", None]
8688
send_images_to_gptvision = overrides.get("gpt4v_input") in ["textAndImages", "images", None]
8789

@@ -90,9 +92,9 @@ async def run(
9092
if use_vector_search:
9193
for field in vector_fields:
9294
vector = (
93-
await self.compute_text_embedding(q)
94-
if field == "embedding"
95-
else await self.compute_image_embedding(q)
95+
await self.compute_image_embedding(q)
96+
if field.startswith("image")
97+
else await self.compute_text_embedding(q)
9698
)
9799
vectors.append(vector)
98100

app/backend/prepdocslib/integratedvectorizerstrategy.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ def __init__(
6060
self.category = category
6161
self.search_info = search_info
6262

63-
async def create_embedding_skill(self, index_name: str):
63+
async def create_embedding_skill(self, index_name: str, embedding_field: str) -> SearchIndexerSkillset:
64+
"""
65+
Create a skillset for the indexer to chunk documents and generate embeddings
66+
"""
6467
skillset_name = f"{index_name}-skillset"
6568

6669
split_skill = SplitSkill(
@@ -87,7 +90,7 @@ async def create_embedding_skill(self, index_name: str):
8790
inputs=[
8891
InputFieldMappingEntry(name="text", source="/document/pages/*"),
8992
],
90-
outputs=[OutputFieldMappingEntry(name="embedding", target_name="vector")],
93+
outputs=[OutputFieldMappingEntry(name=embedding_field, target_name="vector")],
9194
)
9295

9396
index_projection = SearchIndexerIndexProjection(
@@ -98,7 +101,7 @@ async def create_embedding_skill(self, index_name: str):
98101
source_context="/document/pages/*",
99102
mappings=[
100103
InputFieldMappingEntry(name="content", source="/document/pages/*"),
101-
InputFieldMappingEntry(name="embedding", source="/document/pages/*/vector"),
104+
InputFieldMappingEntry(name=embedding_field, source="/document/pages/*/vector"),
102105
InputFieldMappingEntry(name="sourcepage", source="/document/metadata_storage_name"),
103106
],
104107
),

app/backend/prepdocslib/searchmanager.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def __init__(
5555
use_acls: bool = False,
5656
use_int_vectorization: bool = False,
5757
embeddings: Optional[OpenAIEmbeddings] = None,
58+
embedding_field: str = "embedding3", # can we make this not have a default?
5859
search_images: bool = False,
5960
):
6061
self.search_info = search_info
@@ -63,7 +64,9 @@ def __init__(
6364
self.use_int_vectorization = use_int_vectorization
6465
self.embeddings = embeddings
6566
# Integrated vectorization uses the ada-002 model with 1536 dimensions
66-
self.embedding_dimensions = self.embeddings.open_ai_dimensions if self.embeddings else 1536
67+
# TODO: Update integrated vectorization too!
68+
self.embedding_dimensions = self.embeddings.open_ai_dimensions if self.embeddings else None
69+
self.embedding_field = embedding_field
6770
self.search_images = search_images
6871

6972
async def create_index(self, vectorizers: Optional[List[VectorSearchVectorizer]] = None):
@@ -93,7 +96,7 @@ async def create_index(self, vectorizers: Optional[List[VectorSearchVectorizer]]
9396
analyzer_name=self.search_analyzer_name,
9497
),
9598
SearchField(
96-
name="embedding",
99+
name=self.embedding_field,
97100
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
98101
hidden=False,
99102
searchable=True,
@@ -204,9 +207,7 @@ async def create_index(self, vectorizers: Optional[List[VectorSearchVectorizer]]
204207
VectorSearchProfile(
205208
name="embedding_config",
206209
algorithm_configuration_name="hnsw_config",
207-
vectorizer_name=(
208-
f"{self.search_info.index_name}-vectorizer" if self.use_int_vectorization else None
209-
),
210+
vectorizer_name=(f"{self.search_info.index_name}-vectorizer"),
210211
),
211212
],
212213
vectorizers=vectorizers,
@@ -228,7 +229,24 @@ async def create_index(self, vectorizers: Optional[List[VectorSearchVectorizer]]
228229
),
229230
)
230231
await search_index_client.create_or_update_index(existing_index)
231-
232+
# check if embedding field exists
233+
if not any(field.name == self.embedding_field for field in existing_index.fields):
234+
logger.info("Adding embedding field to index %s", self.search_info.index_name)
235+
existing_index.fields.append(
236+
SearchField(
237+
name=self.embedding_field,
238+
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
239+
hidden=False,
240+
searchable=True,
241+
filterable=False,
242+
sortable=False,
243+
facetable=False,
244+
# TODO: use optimizations here
245+
vector_search_dimensions=self.embedding_dimensions,
246+
vector_search_profile_name="embedding_config",
247+
),
248+
)
249+
await search_index_client.create_or_update_index(existing_index)
232250
if existing_index.vector_search is not None and (
233251
existing_index.vector_search.vectorizers is None
234252
or len(existing_index.vector_search.vectorizers) == 0
@@ -289,7 +307,7 @@ async def update_content(
289307
texts=[section.split_page.text for section in batch]
290308
)
291309
for i, document in enumerate(documents):
292-
document["embedding"] = embeddings[i]
310+
document[self.embedding_field] = embeddings[i]
293311
if image_embeddings:
294312
for i, (document, section) in enumerate(zip(documents, batch)):
295313
document["imageEmbedding"] = image_embeddings[section.split_page.page_num]

infra/main.bicep

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,13 @@ param chatHistoryVersion string = 'cosmosdb-v2'
7777
// https://learn.microsoft.com/azure/ai-services/openai/concepts/models?tabs=python-secure%2Cstandard%2Cstandard-chat-completions#standard-deployment-model-availability
7878
@description('Location for the OpenAI resource group')
7979
@allowed([
80+
'australiaeast'
81+
'brazilsouth'
8082
'canadaeast'
8183
'eastus'
8284
'eastus2'
8385
'francecentral'
86+
'germanywestcentral'
8487
'switzerlandnorth'
8588
'uksouth'
8689
'japaneast'
@@ -135,7 +138,7 @@ var chatGpt = {
135138
modelName: !empty(chatGptModelName) ? chatGptModelName : 'gpt-4o-mini'
136139
deploymentName: !empty(chatGptDeploymentName) ? chatGptDeploymentName : 'gpt-4o-mini'
137140
deploymentVersion: !empty(chatGptDeploymentVersion) ? chatGptDeploymentVersion : '2024-07-18'
138-
deploymentSkuName: !empty(chatGptDeploymentSkuName) ? chatGptDeploymentSkuName : 'Standard'
141+
deploymentSkuName: !empty(chatGptDeploymentSkuName) ? chatGptDeploymentSkuName : 'Standard' // TODO, but it will break existing deployments
139142
deploymentCapacity: chatGptDeploymentCapacity != 0 ? chatGptDeploymentCapacity : 30
140143
}
141144

@@ -148,8 +151,8 @@ param embeddingDimensions int = 0
148151
var embedding = {
149152
modelName: !empty(embeddingModelName) ? embeddingModelName : 'text-embedding-3-large'
150153
deploymentName: !empty(embeddingDeploymentName) ? embeddingDeploymentName : 'text-embedding-3-large'
151-
deploymentVersion: !empty(embeddingDeploymentVersion) ? embeddingDeploymentVersion : '1'
152-
deploymentSkuName: !empty(embeddingDeploymentSkuName) ? embeddingDeploymentSkuName : 'GlobalStandard'
154+
deploymentVersion: !empty(embeddingDeploymentVersion) ? embeddingDeploymentVersion : (embeddingModelName == 'text-embedding-ada-002' ? '2' : '1')
155+
deploymentSkuName: !empty(embeddingDeploymentSkuName) ? embeddingDeploymentSkuName : (embeddingModelName == 'text-embedding-ada-002' ? 'Standard' : 'GlobalStandard')
153156
deploymentCapacity: embeddingDeploymentCapacity != 0 ? embeddingDeploymentCapacity : 30
154157
dimensions: embeddingDimensions != 0 ? embeddingDimensions : 3072
155158
}
@@ -163,7 +166,7 @@ var gpt4v = {
163166
modelName: !empty(gpt4vModelName) ? gpt4vModelName : 'gpt-4o'
164167
deploymentName: !empty(gpt4vDeploymentName) ? gpt4vDeploymentName : 'gpt-4o'
165168
deploymentVersion: !empty(gpt4vModelVersion) ? gpt4vModelVersion : '2024-08-06'
166-
deploymentSkuName: !empty(gpt4vDeploymentSkuName) ? gpt4vDeploymentSkuName : 'Standard'
169+
deploymentSkuName: !empty(gpt4vDeploymentSkuName) ? gpt4vDeploymentSkuName : 'Standard' // TODO, but it will break existing deployments
167170
deploymentCapacity: gpt4vDeploymentCapacity != 0 ? gpt4vDeploymentCapacity : 10
168171
}
169172

@@ -176,7 +179,7 @@ var eval = {
176179
modelName: !empty(evalModelName) ? evalModelName : 'gpt-4o'
177180
deploymentName: !empty(evalDeploymentName) ? evalDeploymentName : 'gpt-4o'
178181
deploymentVersion: !empty(evalModelVersion) ? evalModelVersion : '2024-08-06'
179-
deploymentSkuName: !empty(evalDeploymentSkuName) ? evalDeploymentSkuName : 'Standard'
182+
deploymentSkuName: !empty(evalDeploymentSkuName) ? evalDeploymentSkuName : 'Standard' // TODO, but it will break existing deployments
180183
deploymentCapacity: evalDeploymentCapacity != 0 ? evalDeploymentCapacity : 30
181184
}
182185

@@ -1235,6 +1238,7 @@ output AZURE_RESOURCE_GROUP string = resourceGroup.name
12351238
// Shared by all OpenAI deployments
12361239
output OPENAI_HOST string = openAiHost
12371240
output AZURE_OPENAI_EMB_MODEL_NAME string = embedding.modelName
1241+
output AZURE_OPENAI_EMB_DIMENSIONS int = embedding.dimensions
12381242
output AZURE_OPENAI_CHATGPT_MODEL string = chatGpt.modelName
12391243
output AZURE_OPENAI_GPT4V_MODEL string = gpt4v.modelName
12401244

@@ -1243,9 +1247,17 @@ output AZURE_OPENAI_SERVICE string = isAzureOpenAiHost && deployAzureOpenAi ? op
12431247
output AZURE_OPENAI_API_VERSION string = isAzureOpenAiHost ? azureOpenAiApiVersion : ''
12441248
output AZURE_OPENAI_RESOURCE_GROUP string = isAzureOpenAiHost ? openAiResourceGroup.name : ''
12451249
output AZURE_OPENAI_CHATGPT_DEPLOYMENT string = isAzureOpenAiHost ? chatGpt.deploymentName : ''
1250+
output AZURE_OPENAI_CHATGPT_DEPLOYMENT_VERSION string = isAzureOpenAiHost ? chatGpt.deploymentVersion : ''
1251+
output AZURE_OPENAI_CHATGPT_DEPLOYMENT_SKU string = isAzureOpenAiHost ? chatGpt.deploymentSkuName : ''
12461252
output AZURE_OPENAI_EMB_DEPLOYMENT string = isAzureOpenAiHost ? embedding.deploymentName : ''
1253+
output AZURE_OPENAI_EMB_DEPLOYMENT_VERSION string = isAzureOpenAiHost ? embedding.deploymentVersion : ''
1254+
output AZURE_OPENAI_EMB_DEPLOYMENT_SKU string = isAzureOpenAiHost ? embedding.deploymentSkuName : ''
12471255
output AZURE_OPENAI_GPT4V_DEPLOYMENT string = isAzureOpenAiHost && useGPT4V ? gpt4v.deploymentName : ''
1256+
output AZURE_OPENAI_GPT4V_DEPLOYMENT_VERSION string = isAzureOpenAiHost && useGPT4V ? gpt4v.deploymentVersion : ''
1257+
output AZURE_OPENAI_GPT4V_DEPLOYMENT_SKU string = isAzureOpenAiHost && useGPT4V ? gpt4v.deploymentSkuName : ''
12481258
output AZURE_OPENAI_EVAL_DEPLOYMENT string = isAzureOpenAiHost && useEval ? eval.deploymentName : ''
1259+
output AZURE_OPENAI_EVAL_DEPLOYMENT_VERSION string = isAzureOpenAiHost && useEval ? eval.deploymentVersion : ''
1260+
output AZURE_OPENAI_EVAL_DEPLOYMENT_SKU string = isAzureOpenAiHost && useEval ? eval.deploymentSkuName : ''
12491261
output AZURE_OPENAI_EVAL_MODEL string = isAzureOpenAiHost && useEval ? eval.modelName : ''
12501262

12511263
output AZURE_SPEECH_SERVICE_ID string = useSpeechOutputAzure ? speech.outputs.resourceId : ''

0 commit comments

Comments
 (0)