1+ '''
2+ Qwen3 VLM example.
3+ Supportted devices: MaixCAM2
4+ Not Supported devices: MaixCAM
5+ Models:
6+ - https://huggingface.co/sipeed/Qwen3-VL-2B-Instruct-GPTQ-Int4-AX630C-P320-CTX448-maixcam2
7+ '''
8+ from maix import app , nn , err , image , display , time
9+ import requests
10+ import json
11+
12+ model = "/root/models/Qwen3-VL-2B-Instruct-GPTQ-Int4-AX630C-P320-CTX448-maixcam2/model.mud"
13+ disp = display .Display ()
14+
15+ qwen3_vl = nn .Qwen3VL (model )
16+
17+ in_w = qwen3_vl .input_width ()
18+ in_h = qwen3_vl .input_height ()
19+ in_fmt = qwen3_vl .input_format ()
20+ print (f"input size: { in_w } x{ in_h } , format: { image .format_name (in_fmt )} " )
21+
22+ def on_reply (obj , resp ):
23+ print (resp .msg_new , end = "" )
24+
25+ qwen3_vl .set_system_prompt ("You are Qwen3VL. You are a helpful vision-to-text assistant." )
26+ qwen3_vl .set_reply_callback (on_reply )
27+
28+ # load and set image
29+ img = image .load ("/maixapp/share/picture/2024.1.1/ssd_car.jpg" , format = in_fmt )
30+ qwen3_vl .set_image (img , fit = image .Fit .FIT_CONTAIN ) # if size not math, will auto resize first
31+ disp .show (img )
32+
33+ while not app .need_exit ():
34+ print ('wait model is ready' )
35+ if qwen3_vl .is_ready ():
36+ break
37+ time .sleep (1 )
38+
39+ def example1 ():
40+ # set prompt
41+ msg = "请描述图中有什么"
42+ print (">>" , msg )
43+ resp = qwen3_vl .send (msg )
44+ err .check_raise (resp .err_code )
45+
46+ def example2 ():
47+ msg = "Describe the picture"
48+ print (">>" , msg )
49+ resp = qwen3_vl .send (msg )
50+ err .check_raise (resp .err_code )
51+
52+
53+ def example3 ():
54+ url = "http://127.0.0.1:12346"
55+ headers = {
56+ "Content-Type" : "application/json" ,
57+ }
58+
59+ stream = True
60+ data = {
61+ "model" : "AXERA-TECH/Qwen3-VL-2B-Instruct-GPTQ-Int4" ,
62+ "stream" :stream ,
63+ "temperature" :0.7 ,
64+ "repetition_penalty" :1 ,
65+ "top-p" :0.8 ,
66+ "top-k" :20 ,
67+ "messages" : [{
68+ "role" :"user" ,
69+ "content" : [{
70+ "type" :"text" ,
71+ "text" :"告诉我你的名字"
72+ }, {
73+ "type" :"image_url" ,
74+ "image_url" :"images/demo.jpg"
75+ }]
76+ }]
77+ }
78+ response = requests .post (url + '/v1/chat/completions' , headers = headers , json = data , stream = stream )
79+
80+ if not stream :
81+ print (response .status_code ) # 状态码
82+ print (response .text ) # 响应内容
83+ else :
84+ # 处理流式响应
85+ if response .status_code == 200 :
86+ for line in response .iter_lines ():
87+ if line :
88+ line = line .decode ('utf-8' )
89+ if line .startswith ('data: ' ):
90+ data_str = line [6 :] # 移除 "data: " 前缀
91+ if data_str .strip () == '[DONE]' :
92+ print ("\n 流式传输完成" )
93+ break
94+ try :
95+ chunk = json .loads (data_str )
96+ # 提取模型输出内容
97+ if 'choices' in chunk and len (chunk ['choices' ]) > 0 :
98+ delta = chunk ['choices' ][0 ].get ('delta' , {})
99+ if 'content' in delta :
100+ print (delta ['content' ], end = '' , flush = True )
101+ except json .JSONDecodeError :
102+ continue
103+ else :
104+ print (f"请求失败: { response .status_code } " )
105+ print (response .text )
106+
107+
108+ example1 ()
109+ # example2()
110+ # example3()
111+
112+ del qwen3_vl # Must release vlm object
0 commit comments