llama-index
138 строк · 4.4 Кб
1import time
2from functools import partial
3from typing import Callable, List, Optional, Tuple
4
5import pandas as pd
6from llama_index.core import SimpleDirectoryReader
7from llama_index.core.base.embeddings.base import (
8DEFAULT_EMBED_BATCH_SIZE,
9BaseEmbedding,
10)
11from llama_index.embeddings import OpenAIEmbedding, resolve_embed_model
12
13
14def generate_strings(num_strings: int = 100, string_length: int = 10) -> List[str]:
15"""
16Generate random strings sliced from the paul graham essay of the following form:
17
18offset 0: [0:string_length], [string_length:2*string_length], ...
19offset 1: [1:1+string_length], [1+string_length:1+2*string_length],...
20...
21""" # noqa: D415
22content = (
23SimpleDirectoryReader("../../examples/paul_graham_essay/data")
24.load_data()[0]
25.get_content()
26)
27content_length = len(content)
28
29strings_per_loop = content_length / string_length
30num_loops_upper_bound = int(num_strings / strings_per_loop) + 1
31strings = []
32
33for offset in range(num_loops_upper_bound + 1):
34ptr = offset % string_length
35while ptr + string_length < content_length:
36strings.append(content[ptr : ptr + string_length])
37ptr += string_length
38if len(strings) == num_strings:
39break
40
41return strings
42
43
44def create_open_ai_embedding(batch_size: int) -> Tuple[BaseEmbedding, str, int]:
45return (
46OpenAIEmbedding(embed_batch_size=batch_size),
47"OpenAIEmbedding",
484096,
49)
50
51
52def create_local_embedding(
53model_name: str, batch_size: int
54) -> Tuple[BaseEmbedding, str, int]:
55model = resolve_embed_model(f"local:{model_name}")
56return (
57model,
58"hf/" + model_name,
59model._langchain_embedding.client.max_seq_length, # type: ignore
60)
61
62
63def bench_simple_vector_store(
64embed_models: List[Callable[[int], Tuple[BaseEmbedding, str, int]]],
65num_strings: List[int] = [100],
66string_lengths: List[int] = [64, 256],
67embed_batch_sizes: List[int] = [1, DEFAULT_EMBED_BATCH_SIZE],
68torch_num_threads: Optional[int] = None,
69) -> None:
70"""Benchmark embeddings."""
71print("Benchmarking Embeddings\n---------------------------")
72
73results = []
74
75if torch_num_threads is not None:
76import torch # pants: no-infer-dep
77
78torch.set_num_threads(torch_num_threads)
79
80max_num_strings = max(num_strings)
81for string_length in string_lengths:
82generated_strings = generate_strings(
83num_strings=max_num_strings, string_length=string_length
84)
85
86for string_count in num_strings:
87strings = generated_strings[:string_count]
88
89for batch_size in embed_batch_sizes:
90models = []
91for create_model in embed_models:
92models.append(create_model(batch_size=batch_size)) # type: ignore
93
94for model in models:
95time1 = time.time()
96_ = model[0].get_text_embedding_batch(strings, show_progress=True)
97
98time2 = time.time()
99print(
100f"Embedding with model {model[1]} with "
101f"batch size {batch_size} and max_seq_length {model[2]} for "
102f"{string_count} strings of length {string_length} took "
103f"{time2 - time1} seconds."
104)
105results.append((model[1], batch_size, string_length, time2 - time1))
106# TODO: async version
107
108# print final results
109print("\n\nFinal Results\n---------------------------")
110results_df = pd.DataFrame(
111results, columns=["model", "batch_size", "string_length", "time"]
112)
113print(results_df)
114
115
116if __name__ == "__main__":
117bench_simple_vector_store(
118embed_models=[
119# create_open_ai_embedding,
120partial(
121create_local_embedding,
122model_name="sentence-transformers/all-MiniLM-L6-v2",
123),
124partial(
125create_local_embedding,
126model_name="sentence-transformers/all-MiniLM-L12-v2",
127),
128partial(
129create_local_embedding,
130model_name="BAAI/bge-small-en",
131),
132partial(
133create_local_embedding,
134model_name="sentence-transformers/all-mpnet-base-v2",
135),
136],
137torch_num_threads=None,
138)
139