"vscode:/vscode.git/clone" did not exist on "a90c97d72705f57b589062a2e09917dd9d27e389"
restful_api.md 4.97 KB
Newer Older
AllentDan's avatar
AllentDan committed
1
2
3
4
5
6
7
# Restful API

### 启动服务

运行脚本

```shell
8
lmdeploy serve api_server ./workspace 0.0.0.0 --server_port ${server_port} --instance_num 32 --tp 1
AllentDan's avatar
AllentDan committed
9
10
```

11
然后用户可以打开 swagger UI: `http://{server_ip}:{server_port}` 详细查看所有的 API 及其使用方法。
12
13
14
15
16
17
18
我们一共提供四个 restful api,其中三个仿照 OpenAI 的形式。

- /v1/chat/completions
- /v1/models
- /v1/completions

不过,我们建议用户用我们提供的另一个 API: `/v1/chat/interactive`
AllentDan's avatar
AllentDan committed
19
20
21
22
它有更好的性能,提供更多的参数让用户自定义修改。

### python

23
24
25
26
27
28
29
30
31
32
33
34
35
我们将这些服务的客户端功能集成在 `APIClient` 类中。下面是一些例子,展示如何在客户端调用 `api_server` 服务。
如果你想用 `/v1/chat/completions` 接口,你可以尝试下面代码:

```python
from lmdeploy.serve.openai.api_client import APIClient
api_client = APIClient('http://{server_ip}:{server_port}')
model_name = api_client.available_models[0]
messages = [{"role": "user", "content": "Say this is a test!"}]
for item in api_client.chat_completions_v1(model=model_name, messages=messages):
    print(item)
```

如果你想用 `/v1/completions` 接口,你可以尝试:
AllentDan's avatar
AllentDan committed
36
37

```python
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from lmdeploy.serve.openai.api_client import APIClient
api_client = APIClient('http://{server_ip}:{server_port}')
model_name = api_client.available_models[0]
for item in api_client.completions_v1(model=model_name, prompt='hi'):
    print(item)
```

LMDeploy 的 `/v1/chat/interactive` api 支持将对话内容管理在服务端,但是我们默认关闭。如果想尝试,请阅读以下介绍:

- 交互模式下,对话历史保存在 server。在一次完整的多轮对话中,所有请求设置`interactive_mode = True`, `session_id`保持相同 (不为 -1,这是缺省值)。
- 非交互模式下,server 不保存历史记录。

交互模式可以通过 `interactive_mode` 布尔量参数控制。下面是一个普通模式的例子,
如果要体验交互模式,将 `interactive_mode=True` 传入即可。

```python
from lmdeploy.serve.openai.api_client import APIClient
api_client = APIClient('http://{server_ip}:{server_port}')
for item in api_client.generate(prompt='hi'):
    print(item)
AllentDan's avatar
AllentDan committed
58
59
```

60
### Java/Golang/Rust
AllentDan's avatar
AllentDan committed
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
可以使用代码生成工具 [openapi-generator-cli](https://github.com/OpenAPITools/openapi-generator-cli)`http://{server_ip}:{server_port}/openapi.json` 转成 java/rust/golang 客户端。
下面是一个使用示例:

```shell
$ docker run -it --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate -i /local/openapi.json -g rust -o /local/rust

$ ls rust/*
rust/Cargo.toml  rust/git_push.sh  rust/README.md

rust/docs:
ChatCompletionRequest.md  EmbeddingsRequest.md  HttpValidationError.md  LocationInner.md  Prompt.md
DefaultApi.md             GenerateRequest.md    Input.md                Messages.md       ValidationError.md

rust/src:
apis  lib.rs  models
```
AllentDan's avatar
AllentDan committed
78
79
80
81
82
83
84
85

### cURL

cURL 也可以用于查看 API 的输出结果

查看模型列表:

```bash
86
curl http://{server_ip}:{server_port}/v1/models
AllentDan's avatar
AllentDan committed
87
88
```

89
Interactive Chat:
AllentDan's avatar
AllentDan committed
90
91

```bash
92
curl http://{server_ip}:{server_port}/v1/chat/interactive \
AllentDan's avatar
AllentDan committed
93
94
  -H "Content-Type: application/json" \
  -d '{
95
    "prompt": "Hello! How are you?",
96
    "session_id": 1,
97
    "interactive_mode": true
AllentDan's avatar
AllentDan committed
98
99
100
101
102
103
  }'
```

Chat Completions:

```bash
104
curl http://{server_ip}:{server_port}/v1/chat/completions \
AllentDan's avatar
AllentDan committed
105
106
107
  -H "Content-Type: application/json" \
  -d '{
    "model": "internlm-chat-7b",
108
    "messages": [{"role": "user", "content": "Hello! How are you?"}]
AllentDan's avatar
AllentDan committed
109
110
111
  }'
```

112
Text Completions:
AllentDan's avatar
AllentDan committed
113

114
115
116
```shell
curl http://{server_ip}:{server_port}/v1/completions \
  -H 'Content-Type: application/json' \
AllentDan's avatar
AllentDan committed
117
  -d '{
118
119
120
  "model": "llama",
  "prompt": "two steps to build a house:"
}'
AllentDan's avatar
AllentDan committed
121
122
```

123
124
125
126
127
### CLI client

restful api 服务可以通过客户端测试,例如

```shell
128
129
# restful_api_url is what printed in api_server.py, e.g. http://localhost:23333
lmdeploy serve api_client api_server_url
130
131
132
133
134
135
136
```

### webui

也可以直接用 webui 测试使用 restful-api。

```shell
137
138
139
140
# api_server_url 就是 api_server 产生的,比如 http://localhost:23333
# server_name 和 server_port 是用来提供 gradio ui 访问服务的
# 例子: lmdeploy serve gradio http://localhost:23333 --server_name localhost --server_port 6006
lmdeploy serve gradio api_server_url --server_name ${gradio_ui_ip} --server_port ${gradio_ui_port}
141
142
```

AllentDan's avatar
AllentDan committed
143
144
145
146
147
148
149
### FAQ

1. 当返回结果结束原因为 `"finish_reason":"length"`,这表示回话长度超过最大值。
   请添加 `"renew_session": true` 到下一次请求中。

2. 当服务端显存 OOM 时,可以适当减小启动服务时的 `instance_num` 个数

150
3. 当同一个 `session_id` 的请求给 `/v1/chat/interactive` 函数后,出现返回空字符串和负值的 `tokens`,应该是 `session_id` 混乱了,可以先将交互模式关闭,再重新开启。
AllentDan's avatar
AllentDan committed
151

152
4. `/v1/chat/interactive` api 支持多轮对话, 但是默认关闭。`messages` 或者 `prompt` 参数既可以是一个简单字符串表示用户的单词提问,也可以是一段对话历史。