main
py 102 lines 3.42 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Example Python client for embedding API using vLLM API server
4 NOTE:
5 start a supported embeddings model server with `vllm serve`, e.g.
6 vllm serve intfloat/e5-small
7 """
8
9 import argparse
10 import json
11
12 import requests
13 import torch
14
15 from vllm.entrypoints.pooling.utils import (
16 MetadataItem,
17 build_metadata_items,
18 decode_pooling_output,
19 )
20 from vllm.utils.serial_utils import EMBED_DTYPES, ENDIANNESS
21
22
23 def post_http_request(prompt: dict, api_url: str) -> requests.Response:
24 headers = {"User-Agent": "Test Client"}
25 response = requests.post(api_url, headers=headers, json=prompt)
26 return response
27
28
29 def parse_args():
30 parser = argparse.ArgumentParser()
31 parser.add_argument("--host", type=str, default="localhost")
32 parser.add_argument("--port", type=int, default=8000)
33
34 return parser.parse_args()
35
36
37 def main(args):
38 base_url = f"http://{args.host}:{args.port}"
39 models_url = base_url + "/v1/models"
40 embeddings_url = base_url + "/v1/embeddings"
41
42 response = requests.get(models_url)
43 model = response.json()["data"][0]["id"]
44
45 embedding_size = 0
46
47 input_texts = [
48 "The best thing about vLLM is that it supports many different models",
49 ] * 2
50
51 # The OpenAI client does not support the bytes encoding_format.
52 # The OpenAI client does not support the embed_dtype and endianness parameters.
53 for embed_dtype in EMBED_DTYPES:
54 for endianness in ENDIANNESS:
55 prompt = {
56 "model": model,
57 "input": input_texts,
58 "encoding_format": "bytes",
59 "embed_dtype": embed_dtype,
60 "endianness": endianness,
61 }
62 response = post_http_request(prompt=prompt, api_url=embeddings_url)
63 metadata = json.loads(response.headers["metadata"])
64 body = response.content
65 items = [MetadataItem(**x) for x in metadata["data"]]
66
67 embedding = decode_pooling_output(items=items, body=body)
68 embedding = [x.to(torch.float32) for x in embedding]
69 embedding = torch.stack(embedding)
70 embedding_size = embedding.shape[-1]
71 print(embed_dtype, endianness, embedding.shape)
72
73 # The vllm server always sorts the returned embeddings in the order of input. So
74 # returning metadata is not necessary. You can set encoding_format to bytes_only
75 # to let the server not return metadata.
76 for embed_dtype in EMBED_DTYPES:
77 for endianness in ENDIANNESS:
78 prompt = {
79 "model": model,
80 "input": input_texts,
81 "encoding_format": "bytes_only",
82 "embed_dtype": embed_dtype,
83 "endianness": endianness,
84 }
85 response = post_http_request(prompt=prompt, api_url=embeddings_url)
86 body = response.content
87
88 items = build_metadata_items(
89 embed_dtype=embed_dtype,
90 endianness=endianness,
91 shape=(embedding_size,),
92 n_request=len(input_texts),
93 )
94 embedding = decode_pooling_output(items=items, body=body)
95 embedding = [x.to(torch.float32) for x in embedding]
96 embedding = torch.stack(embedding)
97 print(embed_dtype, endianness, embedding.shape)
98
99
100 if __name__ == "__main__":
101 args = parse_args()
102 main(args)