news 2026/4/16 0:46:16

Qwen-Image-2512-SDNQ实战教程:批量生成+自动重命名+文件归档脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qwen-Image-2512-SDNQ实战教程:批量生成+自动重命名+文件归档脚本

Qwen-Image-2512-SDNQ实战教程:批量生成+自动重命名+文件归档脚本

你是不是也遇到过这样的情况:用Web界面一张张生成图片,填提示词、选参数、点按钮、等进度、点下载……一上午过去,只搞定了二十张图?更别说还要手动给每张图改名字、按项目分类存进不同文件夹。重复劳动不仅耗时间,还容易出错——比如把“产品海报_v2”误存成“产品海报_v1”,或者漏掉某张关键图。

今天这篇教程,就是来帮你彻底甩掉这些琐碎操作的。我们不讲模型原理,也不堆参数配置,就聚焦一件事:怎么用最简单的方式,让Qwen-Image-2512-SDNQ Web服务真正为你干活。你会学到一个轻量但实用的Python脚本,它能:

  • 一次性批量提交几十个Prompt,不用手动点;
  • 每张图生成后自动按规则重命名(比如城市夜景_16:9_42781.png);
  • 按宽高比、日期或关键词自动归档到对应文件夹;
  • 失败时自动记录日志,不中断整个流程;
  • 全程静默运行,生成完直接弹出结果目录。

整个过程不需要改一行Web服务代码,也不用碰GPU显存管理——它只是聪明地“调用”你已有的服务。哪怕你刚接触Python,照着抄、改两处路径,就能跑起来。

下面我们就从环境准备开始,一步步带你搭好这个“图片生成流水线”。

1. 前置准备:确认服务已就绪

在写脚本之前,得先确保你的Qwen-Image-2512-SDNQ Web服务已经稳定运行。这不是额外步骤,而是避免后续调试踩坑的关键。

1.1 验证服务是否正常启动

打开终端,执行以下命令检查服务进程:

ps aux | grep "app.py" | grep -v grep

你应该能看到类似这样的输出:

root 12345 0.1 12.3 1234567 89012 ? Sl Jan20 5:23 python /root/Qwen-Image-2512-SDNQ-uint4-svd-r32/app.py

如果没看到,说明服务没起来。可以手动启动一次试试:

cd /root/Qwen-Image-2512-SDNQ-uint4-svd-r32 python app.py

观察控制台输出,重点看有没有报错。正常启动后会显示:

* Running on http://0.0.0.0:7860 * Debug mode: off

小贴士:如果你用的是CSDN星图镜像,服务默认由Supervisor托管,只要镜像启动成功,服务就已在后台运行。无需额外操作。

1.2 测试API连通性

别急着写脚本,先用最简单的curl确认API能通:

curl -X GET http://127.0.0.1:7860/api/health

预期返回:

{"status": "ok"}

再试一个最小化的生成请求(生成一张极简图,快):

curl -X POST http://127.0.0.1:7860/api/generate \ -H "Content-Type: application/json" \ -d '{"prompt":"a red apple on white background", "aspect_ratio":"1:1"}' \ -o test_apple.png

几秒后,当前目录下应该出现test_apple.png。双击打开看看——如果画面清晰、内容合理,说明服务完全ready,可以进入脚本开发阶段了。

2. 批量生成脚本:核心逻辑拆解

这个脚本不追求炫技,只做三件事:发请求、收文件、理目录。我们把它拆成四个模块,每个都用最直白的方式实现。

2.1 模块一:读取Prompt列表(支持多种格式)

你肯定不想每次跑脚本都改代码里的字符串。所以第一件事,是让脚本能从外部读取任务清单。

我们支持两种常用方式:

  • 纯文本文件prompts.txt):每行一个Prompt,简单直接;
  • CSV文件prompts.csv):支持多列,比如prompt,negative_prompt,aspect_ratio,seed,灵活可控。

脚本会自动识别格式。你只需要准备一个文件,放在和脚本同级目录下即可。

示例prompts.txt

a cyberpunk street at night, neon lights, rain puddles a minimalist logo for a coffee brand, flat design, white background a close-up of a golden retriever puppy, soft focus, natural light

示例prompts.csv

prompt,negative_prompt,aspect_ratio,seed "a futuristic city skyline","blurry, text, watermark","16:9",1234 "hand-drawn sketch of a mountain cabin","photorealistic, photo","4:3",5678

脚本会自动跳过空行和以#开头的注释行,方便你临时禁用某条任务。

2.2 模块二:构造请求并调用API

Qwen-Image-2512-SDNQ的API很干净,POST/api/generate,传JSON,返回PNG。难点在于:怎么让批量请求既稳定又不压垮服务?

我们采用“串行+带延迟”的策略——不是为了慢,而是为了稳:

  • 每次只发一个请求;
  • 请求完成后,等待1秒再发下一个;
  • 如果某次失败(比如超时或返回非200),记录错误并继续下一个,不中断整体流程。

这样做的好处是:内存占用极低(不用缓存所有响应),日志清晰(哪条失败一目了然),且完全兼容服务端的线程锁机制,不会触发排队冲突。

核心代码片段(带注释):

import requests import time import os def generate_image(prompt_data, api_url="http://127.0.0.1:7860/api/generate"): """向Qwen-Image API发送单次请求""" payload = { "prompt": prompt_data.get("prompt", ""), "negative_prompt": prompt_data.get("negative_prompt", ""), "aspect_ratio": prompt_data.get("aspect_ratio", "1:1"), "num_steps": prompt_data.get("num_steps", 50), "cfg_scale": prompt_data.get("cfg_scale", 4.0), "seed": prompt_data.get("seed", None) # None表示随机种子 } try: response = requests.post( api_url, json=payload, timeout=300 # 5分钟超时,足够应对长生成 ) if response.status_code == 200: return response.content # 返回原始PNG字节 else: return f"ERROR: HTTP {response.status_code} - {response.text[:100]}" except requests.exceptions.RequestException as e: return f"ERROR: Request failed - {str(e)}"

2.3 模块三:智能重命名与归档

这是最体现“自动化价值”的部分。我们设计了一套命名规则,兼顾可读性、可排序性和信息密度:

{clean_prompt}_{aspect_ratio}_{seed}.png

其中:

  • clean_prompt:把原始Prompt转成文件名安全格式(去掉空格、标点,截取前20字符);
  • aspect_ratio:直接用16:9这类原始值,一眼看出构图;
  • seed:保留种子值,方便复现。

例如:

  • Prompt:a serene lake surrounded by autumn mountains, misty morning
  • 生成文件名:a_serene_lake_surrounded_by_autu_16:9_42781.png

归档逻辑更简单:按宽高比自动建子目录。脚本会创建如下结构:

output/ ├── 1:1/ ├── 16:9/ ├── 9:16/ ├── 4:3/ └── logs/ └── batch_20240125_1430.log

所有16:9的图,自动进16:9/文件夹;所有失败记录,统一进logs/

2.4 模块四:健壮性保障(日志+重试+状态反馈)

真实场景中,网络抖动、服务短暂卡顿、磁盘满等情况无法避免。脚本内置三层防护:

  • 日志全记录:每个请求的输入、耗时、状态、错误详情,全部写入logs/下的时间戳日志;
  • 单次失败不中断:某张图生成失败,不影响后续任务;
  • 基础重试机制:对网络类错误(如连接拒绝)自动重试1次,间隔3秒。

最后,脚本结束时会打印汇总报告:

批量完成!共处理 5 条任务 ✔ 成功生成:3 张 生成失败:2 张(详见 logs/batch_20240125_1430.log) 输出目录:/root/Qwen-Image-2512-SDNQ-uint4-svd-r32/output

3. 完整脚本:复制即用(含详细注释)

下面是你可以直接复制、保存为batch_generate.py并运行的完整脚本。它已通过Python 3.8+测试,无需额外安装依赖(仅需标准库)。

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Qwen-Image-2512-SDNQ 批量生成脚本 功能:读取Prompt列表 → 调用Web API生成图片 → 自动重命名 + 按宽高比归档 作者:技术实践者 """ import os import csv import json import time import requests import re from datetime import datetime from pathlib import Path # ==================== 配置区(只需修改这里) ==================== API_URL = "http://127.0.0.1:7860/api/generate" # Web服务地址 PROMPT_FILE = "prompts.txt" # 或 "prompts.csv" OUTPUT_ROOT = "output" # 输出根目录 DELAY_BETWEEN_REQUESTS = 1 # 请求间隔秒数(防并发冲突) MAX_RETRY = 1 # 网络错误重试次数 # ================================================================= def sanitize_filename(text, max_len=20): """将文本转为安全的文件名(去空格、标点,截断)""" # 只保留字母、数字、下划线、短横线 safe = re.sub(r'[^a-zA-Z0-9_\-\s]', '', text) # 替换空白为下划线,去首尾,限制长度 safe = '_'.join(safe.split())[:max_len] return safe if safe else 'unnamed' def read_prompts(file_path): """读取prompt列表,支持txt和csv格式""" prompts = [] if not os.path.exists(file_path): raise FileNotFoundError(f"Prompt文件未找到:{file_path}") if file_path.endswith('.csv'): with open(file_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: # 清理空值,设置默认值 prompt = row.get('prompt', '').strip() if not prompt: continue prompts.append({ 'prompt': prompt, 'negative_prompt': row.get('negative_prompt', '').strip(), 'aspect_ratio': row.get('aspect_ratio', '1:1').strip(), 'num_steps': int(row.get('num_steps', '50')), 'cfg_scale': float(row.get('cfg_scale', '4.0')), 'seed': int(row.get('seed', '-1')) if row.get('seed') else None }) else: # txt格式:每行一个prompt with open(file_path, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if not line or line.startswith('#'): continue prompts.append({ 'prompt': line, 'negative_prompt': '', 'aspect_ratio': '1:1', 'num_steps': 50, 'cfg_scale': 4.0, 'seed': None }) return prompts def generate_image(payload, url, retry=0): """发送单次生成请求,带重试""" try: start_time = time.time() response = requests.post(url, json=payload, timeout=300) elapsed = time.time() - start_time if response.status_code == 200: return {'status': 'success', 'content': response.content, 'time': elapsed} else: return {'status': 'error', 'msg': f'HTTP {response.status_code}: {response.text[:100]}', 'time': elapsed} except requests.exceptions.RequestException as e: if retry < MAX_RETRY: time.sleep(3) return generate_image(payload, url, retry + 1) else: return {'status': 'error', 'msg': f'Request failed after {MAX_RETRY+1} tries: {str(e)}', 'time': 0} def main(): # 创建输出目录 output_dir = Path(OUTPUT_ROOT) log_dir = output_dir / "logs" log_dir.mkdir(exist_ok=True, parents=True) # 日志文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M") log_file = log_dir / f"batch_{timestamp}.log" # 读取任务 prompts = read_prompts(PROMPT_FILE) if not prompts: print(" 错误:未读取到任何有效Prompt,请检查文件格式和内容。") return print(f" 开始批量生成,共 {len(prompts)} 个任务...") print(f" 日志将保存至:{log_file}") # 统计 success_count = 0 error_count = 0 # 逐个处理 for i, p in enumerate(prompts, 1): print(f"\n--- 任务 {i}/{len(prompts)} ---") print(f"Prompt: {p['prompt'][:50]}{'...' if len(p['prompt']) > 50 else ''}") # 构造文件名 clean_prompt = sanitize_filename(p['prompt']) aspect = p['aspect_ratio'].replace(':', '_') seed_str = str(p['seed']) if p['seed'] else str(int(time.time()))[-5:] filename = f"{clean_prompt}_{aspect}_{seed_str}.png" # 归档目录 sub_dir = output_dir / p['aspect_ratio'] sub_dir.mkdir(exist_ok=True) full_path = sub_dir / filename # 发送请求 result = generate_image(p, API_URL) # 记录日志 with open(log_file, 'a', encoding='utf-8') as lf: lf.write(f"[{datetime.now().strftime('%H:%M:%S')}] Task {i}\n") lf.write(f" Input: {json.dumps(p, ensure_ascii=False)}\n") lf.write(f" File: {full_path}\n") if result['status'] == 'success': # 保存图片 with open(full_path, 'wb') as f: f.write(result['content']) msg = f"✔ 生成成功 ({result['time']:.1f}s) → {full_path}" print(msg) lf.write(f" Status: SUCCESS ({result['time']:.1f}s)\n\n") success_count += 1 else: msg = f" 生成失败 ({result['time']:.1f}s) → {result['msg']}" print(msg) lf.write(f" Status: FAILED ({result['time']:.1f}s) → {result['msg']}\n\n") error_count += 1 # 请求间隔 if i < len(prompts): time.sleep(DELAY_BETWEEN_REQUESTS) # 汇总 print("\n" + "="*50) print(" 批量完成!") print(f"✔ 成功生成:{success_count} 张") print(f" 生成失败:{error_count} 张(详见 {log_file})") print(f" 输出目录:{output_dir.absolute()}") print("="*50) if __name__ == "__main__": main()

4. 实战演示:三步跑通全流程

现在,我们用一个真实例子,走一遍从准备到收获的全过程。

4.1 第一步:准备Prompt文件

在你的Qwen-Image项目根目录(比如/root/Qwen-Image-2512-SDNQ-uint4-svd-r32/)下,新建一个prompts.txt,内容如下:

# 电商主图系列 a high-resolution product shot of wireless earbuds on marble surface, studio lighting, white background a lifestyle photo of a young woman using laptop in cozy cafe, natural light, shallow depth of field # 社交配图系列 a vibrant abstract background with gradient purple and blue, smooth texture, no text a minimalist flat icon set for mobile app: home, search, profile, settings, all in line style

4.2 第二步:保存并运行脚本

将上面的完整脚本复制,保存为batch_generate.py,放在同一目录下。

然后执行:

cd /root/Qwen-Image-2512-SDNQ-uint4-svd-r32 python batch_generate.py

你会看到类似这样的实时输出:

开始批量生成,共 4 个任务... 日志将保存至:/root/Qwen-Image-2512-SDNQ-uint4-svd-r32/output/logs/batch_20240125_1430.log --- 任务 1/4 --- Prompt: a high-resolution product shot of wireless earbuds on marble surface, studio lighting, white background ✔ 生成成功 (42.3s) → /root/.../output/1:1/a_high_resolution_product_shot_of_wireless_earbuds_on_marble_surface_1:1_42781.png --- 任务 2/4 --- Prompt: a lifestyle photo of a young woman using laptop in cozy cafe, natural light, shallow depth of field ✔ 生成成功 (58.7s) → /root/.../output/16:9/a_lifestyle_photo_of_a_young_woman_using_laptop_in_cozy_cafe_16:9_56782.png ...

4.3 第三步:查看成果

几分钟后,打开output/目录,你会看到:

output/ ├── 1:1/ │ └── a_high_resolution_product_shot_of_wireless_earbuds_on_marble_surface_1:1_42781.png ├── 16:9/ │ └── a_lifestyle_photo_of_a_young_woman_using_laptop_in_cozy_cafe_16:9_56782.png ├── logs/ │ └── batch_20240125_1430.log

所有图片已按宽高比分好类,名字自带关键信息,双击就能预览。再也不用一张张拖进文件夹、一个个改名字了。

5. 进阶技巧:让脚本更贴合你的工作流

这个脚本设计为“开箱即用”,但也留出了几个关键扩展点,你可以根据实际需要微调。

5.1 快速切换不同Prompt文件

不想每次改脚本里的PROMPT_FILE?加个命令行参数:

python batch_generate.py --file prompts_v2.csv

只需在脚本开头加几行argparse代码,就能支持。需要的话,我可以单独提供这个增强版。

5.2 按日期自动归档(适合长期项目)

如果你每天都要生成一批图,可以把OUTPUT_ROOT设为动态值:

OUTPUT_ROOT = f"output_{datetime.now().strftime('%Y%m%d')}"

这样每天的输出都会进独立文件夹,历史记录一目了然。

5.3 与现有工具链集成

  • 配合Git:把prompts.txt加入版本控制,团队共享提示词库;
  • 配合定时任务:用crontab每天凌晨自动生成日报配图;
  • 配合通知:生成完成后,用os.system("notify-send '完成!' '3张图已就绪'")(Linux桌面)或邮件提醒。

这些都不是必须的,但当你发现某个环节重复了三次以上,就是时候让它自动化了。

6. 总结:自动化不是替代,而是释放

回看整个过程,我们没有改动Qwen-Image-2512-SDNQ Web服务的一行代码,也没有深入模型推理细节。我们只是在“人机交互层”做了一次小小的优化:把原本需要鼠标点击20次的操作,压缩成一次命令行执行。

这背后体现的,是一种务实的AI工程思维——不追求技术深度,而专注解决真实痛点;不迷信大而全,而相信小而精的工具链。

你学到的不是一个孤立的脚本,而是一种可迁移的方法论:

  • 把重复动作识别出来;
  • 找到服务暴露的标准接口(这里是HTTP API);
  • 用最轻量的胶水代码(Python requests)把它们粘起来;
  • 加上日志、错误处理、状态反馈,让它真正可靠。

下次当你面对另一个Web UI工具时,也可以问自己:它的API在哪里?我能用脚本代替多少次手动操作?

技术的价值,从来不在它多酷炫,而在它多省心。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 22:20:48

零基础玩转FLUX.1-dev:手把手教你生成影院级光影图片

零基础玩转FLUX.1-dev&#xff1a;手把手教你生成影院级光影图片 你有没有盯着一张电影海报发呆过&#xff1f;那种光从窗缝斜切进来、在主角侧脸投下细腻过渡的阴影&#xff0c;连皮肤纹理都泛着真实油光的质感——不是AI常见的塑料感&#xff0c;而是能让人屏住呼吸的“影院…

作者头像 李华
网站建设 2026/4/15 14:40:20

3大维度重构B站用户洞察:智能分析工具的高效应用指南

3大维度重构B站用户洞察&#xff1a;智能分析工具的高效应用指南 【免费下载链接】bilibili-comment-checker B站评论区自动标注成分&#xff0c;支持动态和关注识别以及手动输入 UID 识别 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-comment-checker 在信…

作者头像 李华
网站建设 2026/4/9 5:30:24

Nexus Mods App完全指南:从新手到专家的7个效率跃迁技巧

Nexus Mods App完全指南&#xff1a;从新手到专家的7个效率跃迁技巧 【免费下载链接】NexusMods.App Home of the development of the Nexus Mods App 项目地址: https://gitcode.com/gh_mirrors/ne/NexusMods.App 你是否曾因插件安装冲突导致游戏崩溃&#xff1f;面对数…

作者头像 李华
网站建设 2026/4/16 7:24:53

键盘连击修复与按键响应优化终极解决方案

键盘连击修复与按键响应优化终极解决方案 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker 机械键盘连击问题是影响输入体验的常见故障&am…

作者头像 李华
网站建设 2026/4/16 7:28:56

MedGemma开源模型实战:医学多模态论文复现实验环境一键部署

MedGemma开源模型实战&#xff1a;医学多模态论文复现实验环境一键部署 1. 为什么你需要一个开箱即用的医学多模态实验环境&#xff1f; 你是否试过在本地部署一个医学多模态大模型&#xff1f;下载权重、配置环境、调试依赖、适配显存、修复CUDA版本冲突……还没开始做实验&…

作者头像 李华
网站建设 2026/4/16 7:24:55

如何用Nugget提升下载效率:从并行原理到高级应用

如何用Nugget提升下载效率&#xff1a;从并行原理到高级应用 【免费下载链接】nugget minimalist wget clone written in node. HTTP GET files and downloads them into the current directory 项目地址: https://gitcode.com/gh_mirrors/nu/nugget 在现代网络环境中&a…

作者头像 李华