Skip to content

Commit 397d274

Browse files
authored
Add some scipts to test fio and dfs llm cache on kubernetes cluster. (#1883)
Fixes #1879 Signed-off-by: Ye Cao <[email protected]>
1 parent 44458b4 commit 397d274

File tree

13 files changed

+864
-0
lines changed

13 files changed

+864
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.10
2+
3+
WORKDIR /
4+
5+
COPY master.py /master.py
6+
7+
RUN pip3 install kubernetes
8+
9+
CMD ["python3", "master.py"]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM ghcr.io/v6d-io/v6d/vineyard-python-dev:latest_x86_64 as builder
2+
3+
FROM python:3.10
4+
5+
WORKDIR /
6+
7+
COPY worker.py /worker.py
8+
COPY --from=builder /tmp/vineyard_llm-0.22.1-py3-none-any.whl vineyard_llm-0.22.1-py3-none-any.whl
9+
10+
RUN apt update && \
11+
apt install fio -y
12+
13+
RUN pip3 install vineyard /vineyard_llm-0.22.1-py3-none-any.whl && \
14+
pip3 install networkx==3.1 && \
15+
pip3 install numpy
16+
17+
CMD ["python3", "worker.py"]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
registry = registry.cn-wulanchabu.aliyuncs.com/vineyard
2+
build-images:
3+
docker build -t ${registry}/fs-llm-master:latest -f ./Dockerfile.master .
4+
docker build -t ${registry}/fs-llm-worker:latest -f ./Dockerfile.worker .
5+
push-images:
6+
docker push ${registry}/fs-llm-master:latest
7+
docker push ${registry}/fs-llm-worker:latest
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
## Run llm test on k8s
2+
3+
This document describes how to run the llm test on a Kubernetes cluster.
4+
5+
### Tokenize the prompt file
6+
7+
Suppose you have a [prompt file](./prompt-samples.txt) that contains the conversation info between the user and the chatbot. You can tokenize the prompt file by running the following command:
8+
9+
```bash
10+
$ python tokenize_prompt.py --prompt-file prompt-samples.txt --file-num 1
11+
```
12+
13+
After running the command, you will get a tokenized prompt file named `tokens_0` under the `small_files` directory.
14+
15+
```bash
16+
$ ls small_files
17+
prompts_0.txt tokens_0
18+
```
19+
20+
Also, you could set the `--file-num` to the number of files you want to split the prompt file into. If the prompt file is too large, you can split it into multiple files. Each file will be processed in parallel.
21+
22+
```
23+
$ python tokenize_prompt.py --prompt-file prompt-samples.txt --file-num 2
24+
$ ls small_files
25+
prompts_0.txt prompts_1.txt tokens_0 tokens_1
26+
```
27+
28+
At this point, you can put these token files to the OSS bucket or NAS refer to the [ossutil upload files](https://help.aliyun.com/zh/oss/user-guide/upload-objects-to-oss/?spm=a2c4g.11186623.0.0.4b471c22sHG1EG) or [nas mount](https://help.aliyun.com/zh/nas/user-guide/mount-an-nfs-file-system-on-a-linux-ecs-instance?spm=a2c4g.11186623.0.0.15713eedDgiEYF).
29+
30+
### Build the master and worker images
31+
32+
Before building the master and worker images, you need to build the vineyard-python-dev image first, as we need the llm-cache pypi package.
33+
34+
```bash
35+
$ cd v6d && make -C docker vineyard-python-dev
36+
```
37+
38+
Then, you can build the master and worker images by running the following command:
39+
40+
> Make sure the image registry is set correctly.
41+
42+
```bash
43+
$ cd modules/llm-cache/tests/k8s-test
44+
$ make build-images
45+
```
46+
47+
Next, push the images to the registry:
48+
49+
```bash
50+
$ make push-images
51+
```
52+
53+
### Deploy on the k8s cluster
54+
55+
#### Create the OSS volume
56+
57+
Assume we have put the token files to the OSS bucket, we need to [create the oss secret and oss volume](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/mount-statically-provisioned-oss-volumes#title-hos-c75-12q) first.
58+
59+
#### Create the Distributed FileSystem Volume
60+
61+
The DFS could be NAS or CPFS, you could refer to the [Mount Nas Volume on ACK](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/mount-statically-provisioned-nas-volumes?spm=a2c4g.11186623.0.0.b7c130b7eJHcnf) or [Mount CPFS Volume on ACK](https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/statically-provisioned-cpfs-2-0-volumes-1?spm=a2c4g.11186623.0.0.399a22dbapWWsP) to create the volume.
62+
63+
#### Deploy the worker
64+
65+
After preparing the OSS volume, and DFS volume, you need change the NFS volume name `nas-csi-pvc` to the DFS volume you created before.
66+
67+
> ** Note: ** The CPU resources is important for the performance of worker, you could adjust the `resources.requests.cpu` to get better performance.
68+
69+
Then deploy the worker by running the following command:
70+
71+
```bash
72+
$ kubectl apply -f yamls/worker.yaml
73+
```
74+
75+
#### Deploy the master
76+
77+
After deploying the worker, you need to change `TOKENS_FILE_NUM` environment variable in the `yamls/master.yaml` file to the number of token files you put in the OSS bucket. Also, the OSS VolumeClaimName `oss-pvc` should be set to the OSS volume you created.
78+
79+
Then deploy the master by running the following command:
80+
81+
```bash
82+
$ kubectl apply -f yamls/master.yaml
83+
```
84+
85+
### Show the result
86+
87+
After running the llm test, you can check the result by running the following command:
88+
89+
```bash
90+
$ python show_result.py --kubeconfig-path /your/kubeconfig --label-selector your_label_key=your_label_value
91+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import socket
2+
import random
3+
import os
4+
import time
5+
from multiprocessing import Pool
6+
from kubernetes import client, config
7+
8+
def get_pod_ips(label_selector):
9+
config.load_incluster_config()
10+
api = client.CoreV1Api()
11+
pods = api.list_pod_for_all_namespaces(label_selector=label_selector)
12+
pod_ip_list = []
13+
for pod in pods.items:
14+
pod_ip_list.append(pod.status.pod_ip)
15+
return pod_ip_list
16+
17+
def distribute_prompts(args):
18+
file_name, server_ips = args
19+
token_list = []
20+
with open(f'{file_name}', 'r', encoding='utf-8') as f:
21+
while True:
22+
line = f.readline()
23+
if not line:
24+
break
25+
token_list.append(line)
26+
27+
for token in token_list:
28+
server_ip = random.choice(server_ips)
29+
#time.sleep(random.randint(1, 200)/1000000)
30+
while True:
31+
try:
32+
send_tokens_to_server(server_ip, 8888, token)
33+
break
34+
except Exception as e:
35+
print(f"Error: {e}")
36+
time.sleep(1)
37+
continue
38+
39+
def send_tokens_to_server(server_address, server_port, tokens):
40+
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
41+
clientsocket.connect((server_address, server_port))
42+
clientsocket.send(tokens.encode('utf-8'))
43+
clientsocket.close()
44+
45+
if __name__ == "__main__":
46+
file_num = int(os.environ.get('TOKENS_FILE_NUM', 16))
47+
file_names = [f'/tokens/tokens_{i}' for i in range(file_num)]
48+
pod_selector = os.environ.get('POD_SELECTOR', 'app=fs-llm-test-worker')
49+
server_ips = get_pod_ips(pod_selector)
50+
with Pool(file_num) as p:
51+
p.map(distribute_prompts, [(file_name, server_ips) for file_name in file_names])

0 commit comments

Comments
 (0)