Nunchaku-flux-1-dev数据预处理实战:爬虫获取的图片数据如何用于模型训练
Nunchaku-flux-1-dev数据预处理实战爬虫获取的图片数据如何用于模型训练想训练一个属于自己的AI绘画模型第一步也是最关键的一步就是准备数据。网上那些精美的图片怎么才能变成模型能“吃”得下的“饲料”呢今天我们就来手把手走一遍这个流程。虽然Nunchaku-flux-1-dev本身是一个强大的预训练模型但如果你想让它学会画你想要的特定风格——比如二次元插画、某种建筑风格或者你公司产品的特定外观——你就需要为它准备专门的“教材”。这个“教材”就是高质量的提示词-图像对数据集。我们将从零开始用Python爬虫从网上收集原始图片然后一步步清洗、打标签最终整理成模型训练所需的格式。整个过程就像给模型准备一份精心编写的菜谱食材图片和做法说明提示词都得备齐。1. 准备工作明确目标与搭建环境在开始写代码之前我们得先想清楚两件事要爬什么以及在哪里爬。明确数据目标假设我们想训练一个生成“赛博朋克风格城市街景”的模型。那么我们的目标就是收集大量高质量的、符合这一主题的图片并为每一张图片配上精准的描述文字提示词。搭建Python环境我们需要一个安装了必要库的Python环境。推荐使用Anaconda创建一个独立的虚拟环境避免库版本冲突。# 创建一个新的虚拟环境可选但推荐 conda create -n image_scraper python3.9 conda activate image_scraper # 安装核心库 pip install requests beautifulsoup4 lxml pillow # 如果需要更复杂的爬取如处理JavaScript渲染的页面可以安装selenium # pip install selenium webdriver-manager这里用到的几个库requests用于向网站发送HTTP请求获取网页HTML内容。beautifulsoup4 lxml用来解析HTML像用剪刀一样从复杂的网页代码中精准地“剪”出我们需要的图片链接。pillow (PIL)一个强大的图像处理库后续用来检查和转换图片格式。2. 第一步编写爬虫获取原始图片爬虫的核心逻辑很简单访问网页 - 解析HTML找到图片链接 - 下载图片到本地。我们以一个允许爬取且图片质量较高的免费图库网站为例请注意在实际操作中务必遵守目标网站的robots.txt协议尊重版权仅用于学习研究。2.1 分析网页结构定位图片链接首先我们手动打开目标网页使用浏览器的“检查元素”功能通常是F12键找到图片对应的HTML标签。通常图片会放在img标签的src属性里或者有时藏在data-src这类延迟加载的属性中。假设我们分析的页面结构里图片链接在img classpreview-image src...中。2.2 编写基础爬虫脚本下面是一个基础的爬虫脚本simple_scraper.pyimport os import requests from bs4 import BeautifulSoup from urllib.parse import urljoin import time def download_images(search_query, num_pages3, save_dir./raw_images): 从示例网站下载图片 :param search_query: 搜索关键词如 cyberpunk city street :param num_pages: 要爬取的页数 :param save_dir: 图片保存目录 # 创建保存目录 os.makedirs(save_dir, exist_okTrue) # 模拟一个真实的浏览器请求头避免被简单反爬 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 } base_url https://example-free-image-site.com/search # 请替换为实际网址 downloaded_count 0 for page in range(1, num_pages 1): print(f正在爬取第 {page} 页...) # 构造每一页的URL这里假设分页参数是 page params {q: search_query, page: page} try: response requests.get(base_url, headersheaders, paramsparams, timeout10) response.raise_for_status() # 检查请求是否成功 except requests.RequestException as e: print(f请求第{page}页失败: {e}) continue soup BeautifulSoup(response.content, lxml) # 根据之前分析的HTML结构查找图片标签 # 这里的选择器是示例需要根据实际网站调整 img_tags soup.find_all(img, class_preview-image) if not img_tags: print(f第{page}页未找到图片可能选择器需要调整或页面结构已变。) # 可以尝试打印一部分soup内容来调试 # print(soup.prettify()[:1000]) for img in img_tags: # 获取图片链接 img_url img.get(src) or img.get(data-src) if not img_url: continue # 处理相对链接拼接成完整URL img_url urljoin(base_url, img_url) # 提取一个简单的文件名可以用图片URL的哈希值或序号 file_extension os.path.splitext(img_url)[-1].split(?)[0] # 处理带参数的URL if file_extension.lower() not in [.jpg, .jpeg, .png, .webp, .gif]: file_extension .jpg # 默认后缀 filename f{search_query.replace( , _)}_{downloaded_count:04d}{file_extension} filepath os.path.join(save_dir, filename) # 下载图片 try: img_data requests.get(img_url, headersheaders, timeout15).content with open(filepath, wb) as f: f.write(img_data) downloaded_count 1 print(f已下载: {filename}) time.sleep(0.5) # 礼貌性延迟避免对服务器造成压力 except Exception as e: print(f下载 {img_url} 失败: {e}) print(f爬取结束。共下载 {downloaded_count} 张图片到 {save_dir} 目录。) if __name__ __main__: # 使用示例 download_images(cyberpunk city night, num_pages2, save_dir./raw_cyberpunk)关键点说明请求头Headers添加User-Agent模拟浏览器访问是绕过基础反爬机制的第一步。错误处理使用try...except包裹网络请求和下载过程确保一个链接失败不会导致整个程序崩溃。延迟Sleep在下载间隔加入time.sleep是网络爬虫的“礼仪”能有效降低被封IP的风险。选择器soup.find_all(‘img’, class_‘preview-image’)这一行是核心你需要根据目标网站的实际HTML结构来调整标签名和类名。运行这个脚本后你就能在./raw_cyberpunk文件夹里看到一堆原始图片了。3. 第二步数据清洗与预处理爬下来的图片往往鱼龙混杂可能有尺寸不对的、损坏的、或者完全不相关的。这一步就是“挑菜”和“洗菜”。3.1 基础清洗过滤损坏与无关文件我们写一个清洗脚本clean_images.pyimport os from PIL import Image import shutil def clean_image_folder(raw_dir, cleaned_dir, min_size(512, 512), max_size(4096, 4096), allowed_formats[JPEG, PNG, WEBP]): 清洗图片目录 :param raw_dir: 原始图片目录 :param cleaned_dir: 清洗后图片目录 :param min_size: 最小允许尺寸 (宽高) :param max_size: 最大允许尺寸 (宽高) :param allowed_formats: 允许的图片格式 os.makedirs(cleaned_dir, exist_okTrue) raw_images [f for f in os.listdir(raw_dir) if f.lower().endswith((.png, .jpg, .jpeg, .webp, .gif, .bmp))] cleaned_count 0 removed_count 0 for img_name in raw_images: img_path os.path.join(raw_dir, img_name) try: with Image.open(img_path) as img: img.verify() # 验证文件是否损坏 # 重新打开以获取属性verify后需要重新打开 img Image.open(img_path) # 检查格式 if img.format not in allowed_formats: print(f移除 {img_name}: 格式 {img.format} 不被允许) removed_count 1 continue # 检查尺寸 width, height img.size if width min_size[0] or height min_size[1]: print(f移除 {img_name}: 尺寸过小 ({width}x{height})) removed_count 1 continue if width max_size[0] or height max_size[1]: print(f移除 {img_name}: 尺寸过大 ({width}x{height})) removed_count 1 continue # 检查模式如RGB if img.mode not in [RGB, RGBA]: # 尝试转换为RGB img img.convert(RGB) # 保存到清洗后目录可统一转换格式如JPEG new_filename f{cleaned_count:04d}.jpg new_path os.path.join(cleaned_dir, new_filename) img.save(new_path, JPEG, quality95) cleaned_count 1 except (IOError, SyntaxError, OSError) as e: print(f移除损坏文件 {img_name}: {e}) removed_count 1 continue print(f清洗完成。原始图片 {len(raw_images)} 张保留 {cleaned_count} 张移除 {removed_count} 张。) # 可选删除原始文件夹以节省空间 # shutil.rmtree(raw_dir) if __name__ __main__: clean_image_folder(./raw_cyberpunk, ./cleaned_cyberpunk, min_size(768, 768))这个脚本做了几件事验证完整性用PIL打开并验证图片剔除损坏文件。过滤尺寸只保留分辨率在设定范围内的图片。对于AI训练通常需要一定尺寸如512x512以上以保证质量。统一格式将图片统一转换为RGB模式的JPEG格式方便后续处理。3.2 人工审核与去重可选但重要自动化清洗后最好能快速浏览一遍图片手动删除那些明显不相关、质量极差或重复的图片。你也可以使用一些工具进行感知哈希pHash计算来辅助去重但人工审核对于小规模数据集来说效果更直接。4. 第三步为图片打标签生成提示词这是构建“提示词-图像对”数据集的核心。标签的质量直接决定了模型学习的效果。4.1 手动标注与自动化辅助对于追求高质量的数据集手动编写提示词是最佳选择。你可以为每张图片撰写详细、准确的描述包括主体a futuristic cyberpunk city风格neon-noir style, cinematic lighting细节rain-soaked streets, towering holographic advertisements, flying cars画质high resolution, detailed, 8k但这非常耗时。一个折中的方案是使用现有的图像描述模型Captioning Model来生成初始标签然后进行人工修正。例如可以使用BLIP、CLIP Interrogator等工具。这里提供一个使用transformers库调用BLIP模型进行批量标注的简化示例# 注意首次运行会自动下载模型需要一定时间和网络 import torch from PIL import Image from transformers import BlipProcessor, BlipForConditionalGeneration import os def generate_captions(image_dir, output_filecaptions.txt): 使用BLIP模型为目录下的所有图片生成描述 device cuda if torch.cuda.is_available() else cpu print(f使用设备: {device}) # 加载模型和处理器 processor BlipProcessor.from_pretrained(Salesforce/blip-image-captioning-base) model BlipForConditionalGeneration.from_pretrained(Salesforce/blip-image-captioning-base).to(device) image_files [f for f in os.listdir(image_dir) if f.lower().endswith((.png, .jpg, .jpeg))] captions [] for idx, img_file in enumerate(image_files): img_path os.path.join(image_dir, img_file) try: raw_image Image.open(img_path).convert(RGB) # 预处理 inputs processor(raw_image, return_tensorspt).to(device) # 生成描述 out model.generate(**inputs, max_length50, num_beams5) caption processor.decode(out[0], skip_special_tokensTrue) captions.append(f{img_file}\t{caption}) print(f[{idx1}/{len(image_files)}] {img_file}: {caption}) except Exception as e: print(f处理 {img_file} 时出错: {e}) captions.append(f{img_file}\tERROR) # 保存到文件 with open(output_file, w, encodingutf-8) as f: f.write(\n.join(captions)) print(f描述已保存至 {output_file}) if __name__ __main__: generate_captions(./cleaned_cyberpunk, auto_captions.txt)运行后你会得到一个auto_captions.txt文件里面是每张图片的自动描述。切记这些自动生成的描述通常比较通用你需要打开这个文件结合图片内容进行人工审核和精细化修改补充风格、细节等关键词。4.2 整理成标准格式经过清洗和标注后我们需要将数据整理成模型训练时常用的格式。一种简单通用的格式是JSON Lines.jsonl每行是一个独立的JSON对象包含图片文件名和对应的提示词。编写一个脚本create_dataset.py来整合import json import os def create_jsonl_dataset(image_dir, caption_file, output_jsonldataset.jsonl): 创建JSON Lines格式的数据集文件 :param image_dir: 图片目录 :param caption_file: 标签文件每行格式为“文件名\t提示词” :param output_jsonl: 输出文件 # 读取标签 caption_dict {} with open(caption_file, r, encodingutf-8) as f: for line in f: parts line.strip().split(\t) if len(parts) 2: filename, caption parts caption_dict[filename] caption dataset [] image_files [f for f in os.listdir(image_dir) if f.lower().endswith((.png, .jpg, .jpeg))] for img_file in image_files: if img_file in caption_dict: data_point { file_name: img_file, # 图片文件名 text: caption_dict[img_file] # 对应的提示词 # 可以添加其他字段如“source”, “rating”等 } dataset.append(data_point) else: print(f警告: 图片 {img_file} 没有找到对应的标签已跳过。) # 写入JSON Lines文件 with open(output_jsonl, w, encodingutf-8) as f: for item in dataset: f.write(json.dumps(item, ensure_asciiFalse) \n) print(f数据集创建完成共 {len(dataset)} 条数据。文件保存为: {output_jsonl}) if __name__ __main__: # 假设我们有一个手动修正后的标签文件 manual_captions.txt create_jsonl_dataset(./cleaned_cyberpunk, manual_captions.txt, cyberpunk_dataset.jsonl)现在你得到了一个标准的cyberpunk_dataset.jsonl文件和一个对应的cleaned_cyberpunk图片文件夹。这就是一个可以直接用于许多AI绘画模型如Stable Diffusion、Nunchaku-flux系列模型微调训练的数据集了。5. 总结与后续步骤走完这一趟你应该对从网上抓取图片到做成训练数据集的全过程有了清晰的了解。整个过程有点像淘金从泥沙俱下的河床互联网里挖出矿石原始图片然后经过破碎、筛选、洗选数据清洗最后提炼出纯度可观的金砂高质量图文对。爬虫和数据清洗是体力活也是细心活。其中最关键、最值得花时间的部分是打标签。自动生成的描述能大大减轻负担但最终的效果上限往往取决于你人工修正和润色提示词所投入的精力。一个“a dog”的标签和一个“a fluffy Samoyed dog running happily on a sunny green lawn, high detail, professional photography”的标签教出来的模型水平是天差地别的。有了这个数据集你就可以着手进行下一步了。例如使用像Kohya_ss、DreamBooth这样的工具对Nunchaku-flux-1-dev这类基础模型进行微调让它专门学会绘制你数据集中蕴含的风格。记住数据是AI的基石花在准备高质量数据上的时间最终都会在模型生成的效果上回报给你。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。