MiniCPM-V-4.6 / app.py
zhehuo's picture
Update app.py
188a71d verified
import os
# 1. 环境配置
os.environ['CUDA_VISIBLE_DEVICES'] = '' # 强制 CPU
os.environ['TOKENIZERS_PARALLELISM'] = 'false' # 防止 Gradio 多线程警告
import torch
from transformers import AutoModel, AutoTokenizer
from PIL import Image
import gradio as gr
# 2. 加载模型 (低内存模式)
model_id = "openbmb/MiniCPM-V-4.6"
print("正在加载模型,请耐心等待...")
model = AutoModel.from_pretrained(
model_id,
trust_remote_code=True,
low_cpu_mem_usage=True
).eval() # 确保是推理模式
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
print("模型加载完成!")
# 3. 推理函数
def analyze_image(image, prompt_text):
if image is None:
return "请上传一张图片。"
# 构建符合 MiniCPM-V 4.6 要求的输入格式
msgs = [
{
'role': 'user',
'content': [
{"type": "image", "image": image}, # 包装图片
{"type": "text", "text": prompt_text} # 包装文本
]
}
]
# CPU 上的数据类型处理
with torch.no_grad():
# 1. 构建输入
inputs = tokenizer.apply_chat_template(
msgs,
tokenize=True,
add_generation_prompt=True,
return_tensors="pt"
)
# 2. 移动到设备并转换数据类型 (CPU 强制 float32)
inputs = inputs.to(model.device, dtype=torch.float32)
# 3. 生成回复
outputs = model.generate(
inputs,
max_new_tokens=1024,
temperature=0.7,
do_sample=True
)
# 解码输出
response = tokenizer.decode(outputs, skip_special_tokens=True)
# 提取 Assistant 的回答部分
if 'assistant' in response:
response = response.split('assistant')[-1].strip()
return response
# 4. 构建界面 (注意:这里去掉了 theme 参数)
with gr.Blocks() as demo:
gr.Markdown("## 🖼️ MiniCPM-V 4.6 视觉理解 (CPU 优化版)")
gr.Markdown("上传图片并输入问题,AI 将为你解答。")
with gr.Row():
with gr.Column():
img_input = gr.Image(type="pil", label="上传图片")
txt_input = gr.Textbox(label="输入问题", placeholder="例如:描述这张图片", value="请描述这张图片")
btn = gr.Button("🚀 生成回答", variant="primary")
with gr.Column():
output = gr.Textbox(label="AI 回答", lines=15)
btn.click(fn=analyze_image, inputs=[img_input, txt_input], outputs=output)
# 5. 启动 (theme 移到这里,并删除了 show_api)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
ssr_mode=False, # 禁用服务端渲染,避免异步报错
theme=gr.themes.Soft() # Gradio 6.0 要求 theme 必须放在 launch 里
)