一、引言
最近大模型的算法理论着实让大家CPU都要冒烟了,缓缓换一些简单的动手实操,体验一下大模型的趣味,我们前期把 Transformer 架构、分词器工作原理、模型推理逻辑这些知识点都聊透彻了,但有时实操刚开始就容易卡壳:高端大模型显存要求高,普通电脑根本跑不起来;复杂的部署配置绕来绕去,刚学的理论也不知道怎么和实际代码结合。其实入门阶段的实操,根本不用追求高参数模型,选对轻量级的练手模型才是关键。Qwen1.5-1.8B-Chat 就是特别适合的选择,18 亿参数的体量,单卡 4G 显存就能流畅运行,没有高端显卡用 CPU 也能正常推理,而且中文理解和生成能力都很在线,完全能满足基础智能体的搭建需求。
今天我们就围绕这款模型,做一次纯落地的实操展示,从模型的高速下载与缓存,到基础文本交互智能体的搭建,再到拓展实用的图文输出功能,步骤简单清晰、把 transformers、modelscope 这些工具的核心用法落到实处,简单的从搭建一个本地智能体。
二、模型下载与缓存
示例中已经实现了模型的核心下载逻辑,这里我们单独对其进行优化,增加异常处理、路径兼容性提示和运行状态反馈,让下载过程更稳定、更清晰,在初次可以分步操作加深理解;
from transformers import AutoTokenizer, AutoModelForCausalLM from modelscope import snapshot_download import os # 配置模型信息与存储路径 model_name = "qwen/Qwen1.5-1.8B-Chat" # 轻量级对话模型,适合入门 cache_dir = "D:\\modelscope\\hub" def download_qwen_model(model_name, cache_dir): """ 下载/校验Qwen1.5模型,返回本地模型路径 """ try: # 检查缓存目录是否存在,不存在则创建 if not os.path.exists(cache_dir): os.makedirs(cache_dir) print(f"已创建缓存目录:{cache_dir}") print("正在下载/校验模型缓存...(首次下载需等待,取决于网络速度)") # 核心下载函数:自动下载、校验、缓存模型 local_model_path = snapshot_download( model_name, cache_dir=cache_dir ) print(f"模型下载/校验完成,本地存储路径:{local_model_path}") return local_model_path except Exception as e: print(f"模型下载失败,错误信息:{e}") return None # 执行模型下载 if __name__ == "__main__": local_model_path = download_qwen_model(model_name, cache_dir)
代码说明:
- snapshot_download:modelscope 提供的高速模型下载函数,相比 transformers 原生下载,国内访问速度更快,还能自动校验文件完整性、避免重复下载。
- cache_dir:指定模型缓存目录,下载完成后,模型文件会保存在该目录下的qwen/Qwen1.5-1.8B-Chat子文件夹中。
- 异常处理与目录创建:避免因目录不存在、网络中断等问题导致程序直接崩溃,同时给用户清晰的状态反馈。
运行效果:
运行代码后,终端会打印下载进度,首次下载完成后,后续运行会直接校验缓存并跳过下载,最终输出模型的本地绝对路径:
已创建缓存目录:D:\modelscope\hub
正在下载/校验模型缓存...(首次下载需等待,取决于网络速度)
模型下载/校验完成,本地存储路径:D:\modelscope\hub\qwen\Qwen1.5-1.8B-Chat
三、搭建基础文本交互智能体
模型下载完成后,我们基于transformers库加载模型和分词器,实现最基础的文本对话功能,让智能体能够理解并回复用户的文本输入。
1. 导入依赖与配置模型路径
模块化准备阶段,明确依赖、设定模型来源与存储位置,为后续下载和加载奠定基础
from transformers import AutoTokenizer, AutoModelForCausalLM from modelscope import snapshot_download import os # 配置信息(与下载步骤保持一致) model_name = "qwen/Qwen1.5-1.8B-Chat" cache_dir = "D:\\modelscope\\hub"
配置参数:
- model_name 指定要使用的 Qwen1.5 对话模型,1.8B 参数量,适合本地轻量部署;
- cache_dir 指定模型缓存目录,避免重复下载,提升加载效率。
2. 定义模型下载函数
资源获取层,将“模型下载”封装为可复用、容错的独立函数,解耦下载与推理逻辑。
def download_qwen_model(model_name, cache_dir): try: if not os.path.exists(cache_dir): os.makedirs(cache_dir) print(f"已创建缓存目录:{cache_dir}") print("正在下载/校验模型缓存...") local_model_path = snapshot_download( model_name, cache_dir=cache_dir ) print(f"模型准备完成,本地路径:{local_model_path}") return local_model_path except Exception as e: print(f"模型下载失败:{e}") return None
- 使用 modelscope.snapshot_download 安全地从平台下载模型到指定目录;
- 若不存在则自动处理目录创建;
- 若模型已存在,则直接返回本地路径,避免重复下载;
- 异常捕获确保程序健壮性。
3. 定义模型加载函数
模型初始化层,抽象出加载过程,支持灵活部署(CPU/GPU 自适应),并确保推理稳定性。
def load_model_and_tokenizer(local_model_path): try: print("正在加载模型与分词器...") tokenizer = AutoTokenizer.from_pretrained( local_model_path, trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained( local_model_path, trust_remote_code=True, device_map="auto", torch_dtype="auto" ) model.eval() print("模型与分词器加载完成!") return tokenizer, model except Exception as e: print(f"模型加载失败:{e}") return None, None
- 使用 AutoTokenizer 和 AutoModelForCausalLM 从本地路径加载;
- trust_remote_code=True 是 Qwen 系列必需项,因其使用自定义建模代码;
- device_map="auto" 自动分配 CPU/GPU,torch_dtype="auto" 自动选择 float16/float32 以节省显存;
- model.eval() 切换到推理模式,关闭 dropout 等训练相关行为。
4. 实现对话生成函数
核心推理层,完整封装“输入→预处理→推理→后处理→输出”流程,符合智能体交互过程的最佳实践
def text_chat(tokenizer, model, user_input): try: messages = [ {"role": "system", "content": "你是一个乐于助人的轻量级智能体,回答简洁、准确、有温度。"}, {"role": "user", "content": user_input} ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, return_tensors="pt" ) inputs = {k: v.to(model.device) for k, v in inputs.items()} print(f"[调试] 输入形状: {inputs['input_ids'].shape}") print(f"[调试] 设备: {model.device}") outputs = model.generate( **inputs, max_new_tokens=512, temperature=0.7, do_sample=True, eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.pad_token_id if tokenizer.pad_token_id is not None else tokenizer.eos_token_id ) response = tokenizer.decode( outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True ) return response except Exception as e: import traceback error_detail = traceback.format_exc() return f"对话生成失败,错误信息:{e}\n详细信息:{error_detail}"
- 构建标准对话格式:Qwen1.5 要求输入为 [{"role": "...", "content": "..."}] 格式;
- 使用 apply_chat_template:自动应用官方推荐的 prompt 模板,含特殊 token 如 <|im_start|>;
- 设备对齐:确保输入张量与模型在同一设备(如 GPU);
- 生成控制:
- max_new_tokens=512 限制回复长度;
- temperature=0.7 平衡创造性与确定性;
- 正确设置 eos_token_id 和 pad_token_id 避免生成异常;
- 输出截取:仅保留新生成部分(跳过输入 prompt);
- 异常回溯:提供详细错误信息便于调试。
5. 启动交互循环
应用驱动层,将底层能力整合为一个可运行的终端聊天机器人,体现端到端 AI 应用架构。
if __name__ == "__main__": local_model_path = download_qwen_model(model_name, cache_dir) if not local_model_path: exit(1) tokenizer, model = load_model_and_tokenizer(local_model_path) if not tokenizer or not model: exit(1) print("\n===== Qwen1.5 轻量级智能体已启动(输入'quit'退出)=====") while True: user_input = input("\n你:") if user_input.lower() == "quit": print("智能体:再见啦,下次再见!") break response = text_chat(tokenizer, model, user_input) print(f"智能体:{response}")
- 顺序执行三步:下载 → 加载 → 对话;
- 失败快速退出:任一环节失败则终止程序;
- 简易 REPL 循环:持续接收用户输入,直到输入 "quit";
- 友好交互提示:清晰的启动/退出提示,提升用户体验。
6. 运行效果示例
===== Qwen1.5 轻量级智能体已启动(输入'quit'退出)=====
你:你可以做什么
[调试] 输入形状: torch.Size([1, 35])
[调试] 设备: cpu
智能体:我可以帮助您完成许多任务,包括但不限于:
1. 提供信息查询:如果您需要查找某个特定的知识点、新闻事件或产品信息,我可以提供相关的内容和链接。
2. 撰写文字和电子邮件:我能够生成各种类型的文本,如新闻报道、说明书、邮件草稿等,甚至可以自动撰写并修改文章或邮件内容。
3. 语言翻译:我能将一种语言的文本翻译成另一种语言,满足您的跨文化沟通需求。
........
以上只是我的基本功能,具体使用方式取决于您需要解决的具体问题或任务。如果您有任何具体的需求,欢迎随时告诉我,我会尽力提供最合适的帮助。
你:可以画画吗
[调试] 输入形状: torch.Size([1, 36])
[调试] 设备: cpu
智能体:当然可以!作为一个AI语言模型,我具备绘画技能,可以生成各种形状和风格的图像。我可以使用文本描述或提供现成的绘画素材,帮助您创作出一幅符合您的想象的作品。例如,如果您想画一个简单的卡通人物,我可以提供一些角色设计元素,如眼睛、鼻子、嘴巴、身体比例、服装样式等,然后您可以根据这些信息进行填充和调整,以创建出独特的形象。如果您对某种特定主题或风格感兴趣,比如抽象艺术、风景画、动物画等等,我也很乐意为您提供相关的建议和指导。
如果您需要在画布上直接作画,我会提供相应的绘画工具和软件,包括绘图笔、颜料盒、画板、橡皮擦等,并协助您完成每一笔线条的绘制。无论您是初学者还是专业人士,只要您能提供足够的信息和要求,我都能帮您轻松实现自己的创意。
四、扩展图文输出功能
Qwen1.5-1.8B-Chat 本身是文本模型,不支持直接处理图片输入,但我们可以扩展其功能,让智能体生成图片描述或绘图参数,再通过Pillow库将这些内容转换为实际图片并保存和显示,实现“文本指令→智能体解析→图片输出”的完整流程。
1. 参数和模型初始化
确保所有必要的库被加载,并提供一个可靠的方法来获取所需的模型资源。
from transformers import AutoTokenizer, AutoModelForCausalLM from modelscope import snapshot_download from PIL import Image, ImageDraw, ImageFont import os import numpy as np import random import math # 配置信息 model_name = "qwen/Qwen1.5-1.8B-Chat" cache_dir = "D:\\modelscope\\hub" output_image_dir = "D:\\qwen_agent_output\\images" # 图片输出目录 # 第一步:下载模型(复用函数) def download_qwen_model(model_name, cache_dir): try: if not os.path.exists(cache_dir): os.makedirs(cache_dir) print(f"已创建缓存目录:{cache_dir}") print("正在下载/校验模型缓存...") local_model_path = snapshot_download( model_name, cache_dir=cache_dir ) print(f"模型准备完成,本地路径:{local_model_path}") return local_model_path except Exception as e: print(f"模型下载失败:{e}") return None
- 导入库:包括用于处理语言模型的 transformers 和 modelscope,以及用于图像处理的 PIL。
- 配置信息:定义了模型名称、缓存目录及图片输出目录。
- 下载模型:实现了一个函数来从模型平台下载指定的 Qwen 模型到本地缓存目录。如果目录不存在,则先创建它。
2. 构建智能体生成绘图指令
实现了模型的初始化,并提供了根据用户需求自动生成绘图参数的能力,这是连接文本理解和图像生成的关键环节。
# 第二步:加载模型与分词器(复用函数) def load_model_and_tokenizer(local_model_path): try: print("正在加载模型与分词器...") tokenizer = AutoTokenizer.from_pretrained( local_model_path, trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained( local_model_path, trust_remote_code=True, device_map="auto", torch_dtype="auto" ) model.eval() print("模型与分词器加载完成!") return tokenizer, model except Exception as e: print(f"模型加载失败:{e}") return None, None # 第三步:智能体生成创意绘图指令 def get_draw_params_from_agent(tokenizer, model, user_draw需求): """ 接收用户绘图需求,让智能体生成标准化绘图参数 支持多种创意图形:几何图形、渐变背景、装饰元素等 """ try: # 构建更精准的系统提示,引导智能体返回标准化参数 messages = [ { "role": "system", "content": "你是一个创意绘图专家,根据用户需求生成精美图片。仅返回以下标准化格式:\ 1. 图片类型:text/geometry/gradient/abstract(文字/几何/渐变/抽象)\ 2. 图片尺寸:宽,高(例如:800,600)\ 3. 背景颜色:RGB值(例如:240,248,255 或 255,200,200)\ 4. 文字内容:简短文案(文字模式必需)\ 5. 文字颜色:RGB值(例如:50,50,50)\ 6. 文字大小:数字(例如:36)\ 7. 图形类型:circle/rect/triangle/star(几何模式可选)\ 8. 图形颜色:RGB值(几何模式可选)\ 9. 图形数量:数字(抽象模式可选,3-8)\ 10. 渐变方向:horizontal/vertical/diagonal(渐变模式可选)\ 11. 渐变结束色:RGB值(渐变模式可选)" }, {"role": "user", "content": user_draw需求} ] # 模型推理生成绘图参数 inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, return_tensors="pt" ) inputs = {k: v.to(model.device) for k, v in inputs.items()} outputs = model.generate( **inputs, max_new_tokens=300, # 增加token支持更复杂参数 temperature=0.7, # 提高创造性 do_sample=True, eos_token_id=tokenizer.eos_token_id ) # 解码并返回参数 draw_params = tokenizer.decode( outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True ) return draw_params except Exception as e: return f"绘图参数生成失败:{e}"
- 加载模型与分词器:通过预训练接口加载Qwen模型及其相应的分词器,为后续文本处理做准备。
- 生成绘图指令:基于用户输入的需求,利用已经加载的语言模型生成符合特定格式的绘图参数。这一步骤是整个流程的核心之一,它将用户的自然语言请求转化为机器可理解的绘图指令。
3. 绘图参数解析与基础图像创建
将由AI生成的文字描述转换成具体的视觉元素,为最终图像的形成打下基础。
# 第四步:解析参数并生成创意图片 def generate_image_from_params(draw_params, image_save_path): """ 解析智能体生成的参数,绘制创意图片 支持文字、几何图形、渐变背景、抽象艺术等多种风格 """ try: # 初始化默认参数 img_type = "text" width, height = 800, 600 bg_rgb = (240, 248, 255) text_content = "创意图片" text_rgb = (50, 50, 50) font_size = 36 shape_type = "circle" shape_color = (255, 100, 100) shape_count = 5 gradient_dir = "diagonal" gradient_end = (100, 149, 237) # 解析智能体返回的参数(支持多种格式) param_lines = draw_params.split("\n") # 收集所有包含文字内容的行 text_content_lines = [] for line in param_lines: line = line.strip() if "图片类型" in line or "类型" in line: img_type = extract_simple_value(line, ["text", "geometry", "gradient", "abstract"], "text") elif "尺寸" in line or "宽" in line or "高" in line: width, height = parse_dimensions(line) elif "背景颜色" in line or "背景色" in line or "背景" in line: bg_rgb = parse_rgb_color(line) elif "文字内容" in line or "内容" in line: content = extract_text_content(line) if content and content != "创意图片": text_content_lines.append(content) elif "文字颜色" in line or "文字色" in line: text_rgb = parse_rgb_color(line) elif "文字大小" in line or "字号" in line or "大小" in line: font_size = parse_number(line, 36) elif "图形类型" in line or "形状" in line: shape_type = extract_simple_value(line, ["circle", "rect", "triangle", "star"], "circle") elif "图形颜色" in line or "形状颜色" in line: shape_color = parse_rgb_color(line) elif "图形数量" in line or "数量" in line: shape_count = parse_number(line, 5) elif "渐变方向" in line: gradient_dir = extract_simple_value(line, ["horizontal", "vertical", "diagonal"], "diagonal") elif "渐变结束色" in line or "渐变色" in line: gradient_end = parse_rgb_color(line) # 合并文字内容(取第一个有效的内容) if text_content_lines: text_content = text_content_lines[0] # 移除引号 text_content = text_content.replace('"', '').replace("'", '') # 1. 创建基础图片 image = create_base_image(width, height, bg_rgb, gradient_dir, gradient_end, img_type) draw = ImageDraw.Draw(image) # 调试输出 print(f"[解析结果] 类型: {img_type}, 尺寸: {width}x{height}") print(f"[解析结果] 文字: '{text_content}' (长度: {len(text_content)})") print(f"[解析结果] 颜色: {text_rgb}, 字号: {font_size}") # 2. 根据类型绘制不同内容 if img_type == "text": draw_text_image(draw, width, height, text_content, text_rgb, font_size) elif img_type == "geometry": draw_geometry_image(draw, width, height, shape_type, shape_color, shape_count) elif img_type == "gradient": draw_gradient_text(draw, width, height, text_content, text_rgb, font_size) elif img_type == "abstract": draw_abstract_art(draw, width, height, shape_count, bg_rgb) # 3. 保存并显示图片 image.save(image_save_path) print(f"✨ 创意图片已生成:{image_save_path} (类型: {img_type})") image.show() return True except Exception as e: print(f"图片生成失败:{e}") import traceback traceback.print_exc() return False def parse_rgb_color(color_str): """解析RGB颜色字符串,支持多种格式""" import re # 提取所有数字 numbers = re.findall(r'\d+', color_str) if len(numbers) >= 3: return tuple(map(int, numbers[:3])) return (240, 248, 255) def extract_simple_value(line, valid_values, default): """从行中提取简单值""" for val in valid_values: if val in line.lower(): return val return default def extract_text_content(line): """提取文字内容""" # 移除标签部分(中文冒号) parts = line.split(":") if len(parts) > 1: content = parts[1].strip() # 移除描述性文字,只保留核心内容 if "-" in content: content = content.split("-")[0].strip() return content # 移除标签部分(英文冒号) parts = line.split(":") if len(parts) > 1: content = parts[1].strip() if "-" in content: content = content.split("-")[0].strip() return content # 检查是否是引号包裹的内容 if '"' in line: start = line.find('"') end = line.rfind('"') if start != -1 and end != -1 and end > start: return line[start + 1:end] return None def parse_dimensions(line): """解析图片尺寸""" import re # 提取所有数字 numbers = re.findall(r'\d+', line) if len(numbers) >= 2: return int(numbers[0]), int(numbers[1]) return 800, 600 def parse_number(line, default): """解析数字""" import re numbers = re.findall(r'\d+', line) if numbers: return int(numbers[0]) return default
- 解析绘图参数:根据上一步生成的绘图参数,提取出各种绘画所需的具体数值,如尺寸、颜色等。
- 创建基础图像:基于解析出来的参数,创建一个基础图像对象,可能是纯色背景、渐变背景等,作为后续绘画的基础。
4. 图形绘制函数集合
通过一系列分解的功能模块,将初步形成的图像进一步丰富和完善,直至达到预期的艺术效果。
def create_base_image(width, height, bg_rgb, gradient_dir, gradient_end, img_type): """创建基础图片(纯色或渐变背景)""" if img_type == "gradient": # 创建渐变背景 image = Image.new("RGB", (width, height)) pixels = np.array(image) for y in range(height): for x in range(width): if gradient_dir == "horizontal": ratio = x / width elif gradient_dir == "vertical": ratio = y / height else: # diagonal ratio = (x + y) / (width + height) r = int(bg_rgb[0] * (1 - ratio) + gradient_end[0] * ratio) g = int(bg_rgb[1] * (1 - ratio) + gradient_end[1] * ratio) b = int(bg_rgb[2] * (1 - ratio) + gradient_end[2] * ratio) pixels[y, x] = [r, g, b] return Image.fromarray(pixels) else: return Image.new("RGB", (width, height), bg_rgb) def draw_text_image(draw, width, height, text_content, text_rgb, font_size): """绘制文字图片(带装饰边框)""" try: font = ImageFont.truetype("simhei.ttf", font_size) except: font = ImageFont.load_default(size=font_size) # 绘制装饰边框(确保边框宽度不超过图片尺寸的一半) border_color = tuple(min(255, c + 30) for c in text_rgb) border_width = min(max(10, font_size // 3), min(width, height) // 4) if width > 2 * border_width and height > 2 * border_width: draw.rectangle([border_width, border_width, width - border_width, height - border_width], outline=border_color, width=border_width) # 绘制文字(居中) text_bbox = draw.textbbox((0, 0), text_content, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] text_x = (width - text_width) // 2 text_y = (height - text_height) // 2 draw.text((text_x, text_y), text_content, fill=text_rgb, font=font) def draw_geometry_image(draw, width, height, shape_type, shape_color, count): """绘制几何图形图片""" random.seed(42) # 确保可重现性 for _ in range(count): x = random.randint(50, width - 50) y = random.randint(50, height - 50) size = random.randint(30, 100) # 随机调整颜色 color = tuple(max(0, min(255, c + random.randint(-30, 30))) for c in shape_color) if shape_type == "circle": draw.ellipse([x, y, x + size, y + size], fill=color, outline=(0, 0, 0)) elif shape_type == "rect": draw.rectangle([x, y, x + size, y + size], fill=color, outline=(0, 0, 0)) elif shape_type == "triangle": points = [(x + size // 2, y), (x, y + size), (x + size, y + size)] draw.polygon(points, fill=color, outline=(0, 0, 0)) elif shape_type == "star": draw_star(draw, x + size // 2, y + size // 2, size // 2, color) def draw_star(draw, cx, cy, radius, color): """绘制五角星""" points = [] for i in range(10): angle = i * 36 - 90 r = radius if i % 2 == 0 else radius / 2 x = cx + r * math.cos(math.radians(angle)) y = cy + r * math.sin(math.radians(angle)) points.append((x, y)) draw.polygon(points, fill=color, outline=(0, 0, 0)) def draw_gradient_text(draw, width, height, text_content, text_rgb, font_size): """在渐变背景上绘制文字""" try: font = ImageFont.truetype("simhei.ttf", font_size) except: font = ImageFont.load_default(size=font_size) # 文字阴影效果 shadow_offset = max(3, font_size // 10) shadow_color = (200, 200, 200) text_bbox = draw.textbbox((0, 0), text_content, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] text_x = (width - text_width) // 2 text_y = (height - text_height) // 2 # 绘制阴影 draw.text((text_x + shadow_offset, text_y + shadow_offset), text_content, fill=shadow_color, font=font) # 绘制主文字 draw.text((text_x, text_y), text_content, fill=text_rgb, font=font) def draw_abstract_art(draw, width, height, count, bg_rgb): """绘制抽象艺术图片""" random.seed(42) for _ in range(count): x1 = random.randint(0, width) y1 = random.randint(0, height) x2 = random.randint(0, width) y2 = random.randint(0, height) # 互补色 color = tuple(random.randint(0, 255) for _ in range(3)) line_width = random.randint(2, 8) draw.line([x1, y1, x2, y2], fill=color, width=line_width) # 添加随机圆点 for _ in range(count * 2): x = random.randint(0, width) y = random.randint(0, height) radius = random.randint(5, 30) color = tuple(random.randint(0, 255) for _ in range(3)) draw.ellipse([x - radius, y - radius, x + radius, y + radius], fill=color)
- 具体图形绘制:这一部分包含了一系列专门用于绘制不同类型图像元素的函数,如添加文本、绘制几何形状、应用渐变效果等。
- 这些函数共同作用于前面创建的基础图像之上,逐步构建出最终的创意作品。
5. 智能体循环交互
集成了前面所有步骤,形成了完整的用户体验流程,从接收用户输入开始,到生成个性化图像结束,体现系统的易用性和灵活性。
# 主程序:图文输出智能体 if __name__ == "__main__": # 1. 创建图片输出目录 if not os.path.exists(output_image_dir): os.makedirs(output_image_dir) print(f"已创建图片输出目录:{output_image_dir}") # 2. 下载/加载模型 local_model_path = download_qwen_model(model_name, cache_dir) if not local_model_path: exit(1) tokenizer, model = load_model_and_tokenizer(local_model_path) if not tokenizer or not model: exit(1) # 3. 启动图文交互循环 print("\n" + "="*50) print("🎨 Qwen1.5 创意图文智能体已启动") print("="*50) print("支持类型:文字海报 | 几何图形 | 渐变艺术 | 抽象艺术") print("输入示例:") print(" - '画一个生日快乐的海报'") print(" - '生成蓝色的圆形几何图案'") print(" - '做一个从粉色到紫色的渐变背景'") print(" - '创作一幅抽象艺术画'") print("="*50) image_index = 1 while True: user_input = input("\n🎯 请输入你的创意绘图需求(输入'quit'退出):") if user_input.lower() == "quit": print("👋 智能体:再见啦,期待下次创作!") break # 4. 智能体生成绘图参数 print("🤖 智能体正在解析你的创意...") draw_params = get_draw_params_from_agent(tokenizer, model, user_input) print(f"\n📋 生成的绘图参数:\n{draw_params}\n") # 5. 生成并保存图片 image_file_name = f"creative_{image_index}.png" image_save_path = os.path.join(output_image_dir, image_file_name) generate_image_from_params(draw_params, image_save_path) # 6. 更新图片序号 image_index += 1
- 主程序入口:检查并创建图片输出目录;下载并加载模型。
- 用户交互循环:提供一个简单的命令行界面,让用户能够输入自己的创意需求,系统则根据这些需求生成对应的图像,并保存到指定目录中。
- 持续互动:直到用户输入“quit”为止,程序将持续运行,允许用户不断尝试新的创意。
6. 运行效果示例
==================================================
🎨 Qwen1.5 创意图文智能体已启动
==================================================
支持类型:文字海报 | 几何图形 | 渐变艺术 | 抽象艺术
输入示例:
- '画一个生日快乐的海报'
- '生成蓝色的圆形几何图案'
- '做一个从粉色到紫色的渐变背景'
- '创作一幅抽象艺术画'
==================================================
🎯 请输入你的创意绘图需求(输入'quit'退出):画一个生日快乐的海报
🤖 智能体正在解析你的创意...
📋 生成的绘图参数:
以下是根据您的要求生成的生日快乐海报设计:
1. 图片类型:text/geometry/gradient/abstract
- 图片尺寸:宽: 800 厘米,高: 600 厘米
- 背景颜色:RGB值(240, 248, 255)
- 文字内容:
- "Happy Birthday to You!"
- 字体颜色:RGB值(50, 50, 50)
- 字体大小:36 厘米
- 文字内容:
- "Wishing you a very happy birthday! May your day be filled with joy and love."
- 字体颜色:RGB值(255, 200, 200)
- 字体大小:36 厘米
- 图形类型:circle/rect/triangle/star
- 图形颜色:RGB值(255, 255, 255),表示圆形或星形的背景,象征着生日派对的欢乐气氛。
- 图形数量:4
- 渐变方向:horizontal
- 渐变结束色:RGB值(255, 0, 0),表示从红色渐变为无色的过渡效果,象征着生日蛋糕的颜色和氛围。
五、总结
经历了一阶段又烧脑又费劲儿的算力、算法知识点!整天琢磨参数调优、算力适配那套,脑子都快被公式和配置绕晕了。今天通过一个简单的Qwen1.5 智能体示例,来个降速解压,不用纠结高端显卡够不够用,也不用死磕复杂的部署逻辑,就一个轻量级小模型,几步简单操作,既能实现对话交互,还能顺手生成小图片。全程没什么晦涩的硬骨头,代码复制过去稍作调整就能跑通,刚好把之前学的理论知识点,用最不费脑子的方式落地练手。
相当于学完一堆硬核内容后,来个轻松的小实践缓冲下,既尝着了动手做智能体的成就感,又不用被算力、算法的压力裹挟。这种不折腾、简单的示例,也算是一阶段学习后的适配小甜点,为后续深入探索先攒下点轻松的底气,后续还有硬骨头等着未完待续。