我在使用Vertex AI的TextEmbeddingModel计算嵌入时发现,第一个调用的延迟明显高于其他调用,这可能是由于缓存引起的。然而,这并不是上下文缓存,并且sdk_encode是逐个调用的。我该如何预热系统以减少初始延迟?
import time import google.generativeai as genai from vertexai.language_models import TextEmbeddingInput, TextEmbeddingModel base_model_name = "text-embedding-004" EMBED_TASK_TYPE = "RETRIEVAL_QUERY" text_embedding_model = TextEmbeddingModel.from_pretrained(base_model_name) model = TextEmbeddingModel.from_pretrained(base_model_name) def sdk_encode( text): inputs = [TextEmbeddingInput(text.lower(), EMBED_TASK_TYPE) ] kwargs = {} embeddings = model.get_embeddings(inputs, **kwargs) text_embeddings = [embedding.values for embedding in embeddings] return text_embeddings[0] if len(text_embeddings) == 1 else text_embeddings queries = ["I want to take pto Monday", "I want to take pto Tuesday", "I want to take pto Friday"] for i in range(3): query = queries[i] start_time = time.time() sdk_encode(query) end_time = time.time() sdk_delay = end_time - start_time print(f"Vertext SDK Latency for {query}: {sdk_delay}")
输出:
Vertext SDK Latency for I want to take pto Monday: 1.3506088256835938Vertext SDK Latency for I want to take pto Tuesday: 0.12767696380615234Vertext SDK Latency for I want to take pto Friday: 0.12481999397277832
回答:
很遗憾,我无法复制您发现的现象(即对嵌入模型的第一次调用时间较长)。我尝试在一个Colab笔记本中进行了测试,供参考。
然而,我注意到您以这种方式循环处理查询似乎没有必要。我发现当您仅嵌入三个字符串时,几乎所有的延迟都来自于重复的调用。
通过实验,我发现没有什么能阻止您将所有查询作为同一语句的一部分发送给VertexAI。从响应回来的速度不比您任何单个函数调用慢来看,库一定是将查询批处理并同时处理的。
试试这个:
import timeimport google.generativeai as genaifrom vertexai.language_models import TextEmbeddingInput, TextEmbeddingModelmodel = TextEmbeddingModel.from_pretrained("text-embedding-004")inputs = [TextEmbeddingInput(text.lower(), "RETRIEVAL_QUERY") for text in queries]st = time.time()embeddings = [e.values for e in model.get_embeddings(inputs)]et = time.time()print(f"Vertex SDK Latency: {et - st}")
可以推测,随着您向批次中添加更多字符串,您会看到延迟增加(因为延迟开始主要由处理时间而不是I/O时间主导)。
如果这成为一个问题,可能值得尝试不同的VertexAI预训练模型——有些模型在生成嵌入时可能比其他模型更快。