yuccaaa commited on
Commit
f185340
·
verified ·
1 Parent(s): acefbcd

Upload ms-swift/examples/infer/demo_mllm.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. ms-swift/examples/infer/demo_mllm.py +145 -0
ms-swift/examples/infer/demo_mllm.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Alibaba, Inc. and its affiliates.
2
+ import os
3
+ from typing import List, Literal
4
+
5
+ os.environ['CUDA_VISIBLE_DEVICES'] = '0'
6
+
7
+
8
+ def infer_batch(engine: 'InferEngine', infer_requests: List['InferRequest']):
9
+ request_config = RequestConfig(max_tokens=512, temperature=0)
10
+ metric = InferStats()
11
+ resp_list = engine.infer(infer_requests, request_config, metrics=[metric])
12
+ query0 = infer_requests[0].messages[0]['content']
13
+ print(f'query0: {query0}')
14
+ print(f'response0: {resp_list[0].choices[0].message.content}')
15
+ print(f'metric: {metric.compute()}')
16
+ # metric.reset() # reuse
17
+
18
+
19
+ def infer_stream(engine: 'InferEngine', infer_request: 'InferRequest'):
20
+ request_config = RequestConfig(max_tokens=512, temperature=0, stream=True)
21
+ metric = InferStats()
22
+ gen_list = engine.infer([infer_request], request_config, metrics=[metric])
23
+ query = infer_request.messages[0]['content']
24
+ print(f'query: {query}\nresponse: ', end='')
25
+ for resp in gen_list[0]:
26
+ if resp is None:
27
+ continue
28
+ print(resp.choices[0].delta.content, end='', flush=True)
29
+ print()
30
+ print(f'metric: {metric.compute()}')
31
+
32
+
33
+ def get_message(mm_type: Literal['text', 'image', 'video', 'audio']):
34
+ if mm_type == 'text':
35
+ message = {'role': 'user', 'content': 'who are you?'}
36
+ elif mm_type == 'image':
37
+ message = {
38
+ 'role':
39
+ 'user',
40
+ 'content': [
41
+ {
42
+ 'type': 'image',
43
+ # url or local_path or PIL.Image or base64
44
+ 'image': 'http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/animal.png'
45
+ },
46
+ {
47
+ 'type': 'text',
48
+ 'text': 'How many sheep are there in the picture?'
49
+ }
50
+ ]
51
+ }
52
+
53
+ elif mm_type == 'video':
54
+ message = {
55
+ 'role':
56
+ 'user',
57
+ 'content': [{
58
+ 'type': 'video',
59
+ 'video': 'https://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/baby.mp4'
60
+ }, {
61
+ 'type': 'text',
62
+ 'text': 'Describe this video.'
63
+ }]
64
+ }
65
+ elif mm_type == 'audio':
66
+ message = {
67
+ 'role':
68
+ 'user',
69
+ 'content': [{
70
+ 'type': 'audio',
71
+ 'audio': 'http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/weather.wav'
72
+ }, {
73
+ 'type': 'text',
74
+ 'text': 'What does this audio say?'
75
+ }]
76
+ }
77
+ return message
78
+
79
+
80
+ def get_data(mm_type: Literal['text', 'image', 'video', 'audio']):
81
+ data = {}
82
+ if mm_type == 'text':
83
+ messages = [{'role': 'user', 'content': 'who are you?'}]
84
+ elif mm_type == 'image':
85
+ # The number of <image> tags must be the same as len(images).
86
+ messages = [{'role': 'user', 'content': '<image>How many sheep are there in the picture?'}]
87
+ # Support URL/Path/base64/PIL.Image
88
+ data['images'] = ['http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/animal.png']
89
+ elif mm_type == 'video':
90
+ messages = [{'role': 'user', 'content': '<video>Describe this video.'}]
91
+ data['videos'] = ['https://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/baby.mp4']
92
+ elif mm_type == 'audio':
93
+ messages = [{'role': 'user', 'content': '<audio>What does this audio say?'}]
94
+ data['audios'] = ['http://modelscope-open.oss-cn-hangzhou.aliyuncs.com/images/weather.wav']
95
+ data['messages'] = messages
96
+ return data
97
+
98
+
99
+ if __name__ == '__main__':
100
+ # The inference of the trained model can be referred to as:
101
+ # https://github.com/modelscope/ms-swift/tree/main/examples/notebook
102
+ from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig, load_dataset
103
+ from swift.plugin import InferStats
104
+ infer_backend = 'pt'
105
+
106
+ if infer_backend == 'pt':
107
+ model = 'Qwen/Qwen2-Audio-7B-Instruct'
108
+ mm_type = 'audio'
109
+ engine = PtEngine(model, max_batch_size=64)
110
+ elif infer_backend == 'vllm':
111
+ # test env: vllm==0.7.3, transformers==4.49.*
112
+ # The meaning of environment variables can be found at:
113
+ # https://swift.readthedocs.io/zh-cn/latest/Instruction/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0.html#id17
114
+ from swift.llm import VllmEngine
115
+ os.environ['MAX_PIXELS'] = '1003520'
116
+ os.environ['VIDEO_MAX_PIXELS'] = '50176'
117
+ os.environ['FPS_MAX_FRAMES'] = '12'
118
+ model = 'Qwen/Qwen2.5-VL-3B-Instruct'
119
+ # If you encounter insufficient GPU memory, please reduce `max_model_len` and set `max_num_seqs=5`.
120
+ engine = VllmEngine(model, max_model_len=8192, limit_mm_per_prompt={'image': 5, 'video': 2})
121
+ mm_type = 'image' # or 'video'
122
+ elif infer_backend == 'lmdeploy':
123
+ # test env: lmdeploy==0.7.1
124
+ from swift.llm import LmdeployEngine
125
+ model = 'OpenGVLab/InternVL2_5-1B'
126
+ engine = LmdeployEngine(model, vision_batch_size=8)
127
+ mm_type = 'image' # or 'video'
128
+
129
+ # infer dataset
130
+ if mm_type == 'audio':
131
+ dataset = 'speech_asr/speech_asr_aishell1_trainsets:validation#1000'
132
+ elif mm_type == 'image':
133
+ dataset = 'AI-ModelScope/LaTeX_OCR:small#1000'
134
+ elif mm_type == 'video':
135
+ dataset = 'swift/VideoChatGPT:Generic#100'
136
+
137
+ # Here, `load_dataset` is used for convenience; `infer_batch` does not require creating a dataset.
138
+ dataset = load_dataset([dataset], seed=42)[0]
139
+ print(f'dataset: {dataset}')
140
+ infer_requests = [InferRequest(**data) for data in dataset]
141
+ infer_batch(engine, infer_requests)
142
+
143
+ infer_stream(engine, InferRequest(messages=[get_message(mm_type)]))
144
+ # This writing is equivalent to the above writing.
145
+ infer_stream(engine, InferRequest(**get_data(mm_type)))