登峰造极,师出造化,Pytorch人工智能AI图像增强框架ControlNet绘画实践,基于Python3.10

简介: 人工智能太疯狂,传统劳动力和内容创作平台被AI枪毙,弃尸尘埃。并非空穴来风,也不是危言耸听,人工智能AI图像增强框架ControlNet正在疯狂地改写绘画艺术的发展进程,你问我绘画行业未来的样子?我只好指着ControlNet的方向。本次我们在M1/M2芯片的Mac系统下,体验人工智能登峰造极的绘画艺术。

人工智能太疯狂,传统劳动力和内容创作平台被AI枪毙,弃尸尘埃。并非空穴来风,也不是危言耸听,人工智能AI图像增强框架ControlNet正在疯狂地改写绘画艺术的发展进程,你问我绘画行业未来的样子?我只好指着ControlNet的方向。本次我们在M1/M2芯片的Mac系统下,体验人工智能登峰造极的绘画艺术。

本地安装和配置ControlNet

ControlNet在HuggingFace训练平台上也有体验版,请参见: https://huggingface.co/spaces/hysts/ControlNet,但由于公共平台算力有限,同时输入参数也受到平台的限制,一次只能训练一张图片,不能让人开怀畅饮。

为了能和史上最伟大的图像增强框架ControlNet一亲芳泽,我们选择本地搭建ControlNet环境,首先运行Git命令拉取官方的线上代码:

git clone https://github.com/lllyasviel/ControlNet.git

拉取成功后,进入项目目录:

cd ControlNet

由于Github对文件大小有限制,所以ControlNet的训练模型只能单独下载,模型都放在HuggingFace平台上:https://huggingface.co/lllyasviel/ControlNet/tree/main/models,需要注意的是,每个模型的体积都非常巨大,达到了5.71G,令人乍舌。

下载好模型后,需要将其放到ControlNet的models目录中:

├── models  
│ ├── cldm_v15.yaml  
│ ├── cldm_v21.yaml  
│ └── control_sd15_canny.pth

这里笔者下载了control\_sd15\_canny.pth模型,即放入models目录中,其他模型也是一样。

随后安装运行环境,官方推荐使用conda虚拟环境,安装好conda后,运行命令激活虚拟环境即可:

conda env create -f environment.yaml  
conda activate control

但笔者查看了官方的environment.yaml配置文件:

name: control  
channels:  
  - pytorch  
  - defaults  
dependencies:  
  - python=3.8.5  
  - pip=20.3  
  - cudatoolkit=11.3  
  - pytorch=1.12.1  
  - torchvision=0.13.1  
  - numpy=1.23.1  
  - pip:  
      - gradio==3.16.2  
      - albumentations==1.3.0  
      - opencv-contrib-python==4.3.0.36  
      - imageio==2.9.0  
      - imageio-ffmpeg==0.4.2  
      - pytorch-lightning==1.5.0  
      - omegaconf==2.1.1  
      - test-tube>=0.7.5  
      - streamlit==1.12.1  
      - einops==0.3.0  
      - transformers==4.19.2  
      - webdataset==0.2.5  
      - kornia==0.6  
      - open_clip_torch==2.0.2  
      - invisible-watermark>=0.1.5  
      - streamlit-drawable-canvas==0.8.0  
      - torchmetrics==0.6.0  
      - timm==0.6.12  
      - addict==2.4.0  
      - yapf==0.32.0  
      - prettytable==3.6.0  
      - safetensors==0.2.7  
      - basicsr==1.4.2

一望而知,Python版本是老旧的3.8,Torch版本1.12并不支持Mac独有的Mps训练模式。

同时,Conda环境也有一些缺点:

环境隔离可能会导致一些问题。虽然虚拟环境允许您管理软件包的版本和依赖关系,但有时也可能导致环境冲突和奇怪的错误。

Conda环境可以占用大量磁盘空间。每个环境都需要独立的软件包副本和依赖项。如果需要创建多个环境,这可能会导致磁盘空间不足的问题。

软件包可用性和兼容性也可能是一个问题。Conda环境可能不包含某些软件包或库,或者可能不支持特定操作系统或硬件架构。

在某些情况下,Conda环境的创建和管理可能会变得复杂和耗时。如果需要管理多个环境,并且需要在这些环境之间频繁切换,这可能会变得困难。

所以我们也可以用最新版的Python3.10来构建ControlNet训练环境,编写requirements.txt文件:

pytorch==1.13.0  
gradio==3.16.2  
albumentations==1.3.0  
opencv-contrib-python==4.3.0.36  
imageio==2.9.0  
imageio-ffmpeg==0.4.2  
pytorch-lightning==1.5.0  
omegaconf==2.1.1  
test-tube>=0.7.5  
streamlit==1.12.1  
einops==0.3.0  
transformers==4.19.2  
webdataset==0.2.5  
kornia==0.6  
open_clip_torch==2.0.2  
invisible-watermark>=0.1.5  
streamlit-drawable-canvas==0.8.0  
torchmetrics==0.6.0  
timm==0.6.12  
addict==2.4.0  
yapf==0.32.0  
prettytable==3.6.0  
safetensors==0.2.7  
basicsr==1.4.2

随后,运行命令:

pip3 install -r requirements.txt

至此,基于Python3.10来构建ControlNet训练环境就完成了,关于Python3.10的安装,请移玉步至:一网成擒全端涵盖,在不同架构(Intel x86/Apple m1 silicon)不同开发平台(Win10/Win11/Mac/Ubuntu)上安装配置Python3.10开发环境,这里不再赘述。

修改训练模式(Cuda/Cpu/Mps)

ControlNet的代码中将训练模式写死为Cuda,CUDA是NVIDIA开发的一个并行计算平台和编程模型,因此不支持NVIDIA GPU的系统将无法运行CUDA训练模式。

除此之外,其他不支持CUDA训练模式的系统可能包括:

没有安装NVIDIA GPU驱动程序的系统

没有安装CUDA工具包的系统

使用的NVIDIA GPU不支持CUDA(较旧的GPU型号可能不支持CUDA)

没有足够的GPU显存来运行CUDA训练模式(尤其是在训练大型深度神经网络时需要大量显存)

需要注意的是,即使系统支持CUDA,也需要确保所使用的机器学习框架支持CUDA,否则无法使用CUDA进行训练。

我们可以修改代码将训练模式改为Mac支持的Mps,请参见:闻其声而知雅意,M1 Mac基于PyTorch(mps/cpu/cuda)的人工智能AI本地语音识别库Whisper(Python3.10),这里不再赘述。

如果代码运行过程中,报下面的错误:

RuntimeError: Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.

说明当前系统不支持cuda模型,需要修改几个地方,以项目中的gradio\_canny2image.py为例子,需要将gradio\_canny2image.py文件中的cuda替换为cpu,同时修改/ControlNet/ldm/modules/encoders/modules.py文件,将cuda替换为cpu,修改/ControlNet/cldm/ddim\_hacked.py文件,将cuda替换为cpu。至此,训练模式就改成cpu了。

开始训练

修改完代码后,直接在终端运行gradio\_canny2image.py文件:

python3 gradio_canny2image.py

程序返回:

➜  ControlNet git:(main) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/ControlNet/gradio_cann  
y2image.py"  
logging improved.  
No module 'xformers'. Proceeding without it.  
/opt/homebrew/lib/python3.10/site-packages/pytorch_lightning/utilities/distributed.py:258: LightningDeprecationWarning: `pytorch_lightning.utilities.distributed.rank_zero_only` has been deprecated in v1.8.1 and will be removed in v2.0.0. You can import it from `pytorch_lightning.utilities` instead.  
  rank_zero_deprecation(  
ControlLDM: Running in eps-prediction mode  
DiffusionWrapper has 859.52 M params.  
making attention of type 'vanilla' with 512 in_channels  
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.  
making attention of type 'vanilla' with 512 in_channels  
Loaded model config from [./models/cldm_v15.yaml]  
Loaded state_dict from [./models/control_sd15_canny.pth]  
Running on local URL:  http://0.0.0.0:7860  
  
To create a public link, set `share=True` in `launch()`.

此时,在本地系统的7860端口上会运行ControlNet的Web客户端服务。

访问 http://localhost:7860,就可以直接上传图片进行训练了。

这里以本站的Logo图片为例子:

通过输入引导词和其他训练参数,就可以对现有图片进行扩散模型的增强处理,这里的引导词的意思是:红宝石、黄金、油画。训练结果可谓是言有尽而意无穷了。

除了主引导词,系统默认会添加一些辅助引导词,比如要求图像品质的best quality, extremely detailed等等,完整代码:

from share import *  
import config  
  
import cv2  
import einops  
import gradio as gr  
import numpy as np  
import torch  
import random  
  
from pytorch_lightning import seed_everything  
from annotator.util import resize_image, HWC3  
from annotator.canny import CannyDetector  
from cldm.model import create_model, load_state_dict  
from cldm.ddim_hacked import DDIMSampler  
  
  
apply_canny = CannyDetector()  
  
model = create_model('./models/cldm_v15.yaml').cpu()  
model.load_state_dict(load_state_dict('./models/control_sd15_canny.pth', location='cpu'))  
model = model.cpu()  
ddim_sampler = DDIMSampler(model)  
  
  
def process(input_image, prompt, a_prompt, n_prompt, num_samples, image_resolution, ddim_steps, guess_mode, strength, scale, seed, eta, low_threshold, high_threshold):  
    with torch.no_grad():  
        img = resize_image(HWC3(input_image), image_resolution)  
        H, W, C = img.shape  
  
        detected_map = apply_canny(img, low_threshold, high_threshold)  
        detected_map = HWC3(detected_map)  
  
        control = torch.from_numpy(detected_map.copy()).float().cpu() / 255.0  
        control = torch.stack([control for _ in range(num_samples)], dim=0)  
        control = einops.rearrange(control, 'b h w c -> b c h w').clone()  
  
        if seed == -1:  
            seed = random.randint(0, 65535)  
        seed_everything(seed)  
  
        if config.save_memory:  
            model.low_vram_shift(is_diffusing=False)  
  
        cond = {"c_concat": [control], "c_crossattn": [model.get_learned_conditioning([prompt + ', ' + a_prompt] * num_samples)]}  
        un_cond = {"c_concat": None if guess_mode else [control], "c_crossattn": [model.get_learned_conditioning([n_prompt] * num_samples)]}  
        shape = (4, H // 8, W // 8)  
  
        if config.save_memory:  
            model.low_vram_shift(is_diffusing=True)  
  
        model.control_scales = [strength * (0.825 ** float(12 - i)) for i in range(13)] if guess_mode else ([strength] * 13)  # Magic number. IDK why. Perhaps because 0.825**12<0.01 but 0.826**12>0.01  
        samples, intermediates = ddim_sampler.sample(ddim_steps, num_samples,  
                                                     shape, cond, verbose=False, eta=eta,  
                                                     unconditional_guidance_scale=scale,  
                                                     unconditional_conditioning=un_cond)  
  
        if config.save_memory:  
            model.low_vram_shift(is_diffusing=False)  
  
        x_samples = model.decode_first_stage(samples)  
        x_samples = (einops.rearrange(x_samples, 'b c h w -> b h w c') * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)  
  
        results = [x_samples[i] for i in range(num_samples)]  
    return [255 - detected_map] + results  
  
  
block = gr.Blocks().queue()  
with block:  
    with gr.Row():  
        gr.Markdown("## Control Stable Diffusion with Canny Edge Maps")  
    with gr.Row():  
        with gr.Column():  
            input_image = gr.Image(source='upload', type="numpy")  
            prompt = gr.Textbox(label="Prompt")  
            run_button = gr.Button(label="Run")  
            with gr.Accordion("Advanced options", open=False):  
                num_samples = gr.Slider(label="Images", minimum=1, maximum=12, value=1, step=1)  
                image_resolution = gr.Slider(label="Image Resolution", minimum=256, maximum=768, value=512, step=64)  
                strength = gr.Slider(label="Control Strength", minimum=0.0, maximum=2.0, value=1.0, step=0.01)  
                guess_mode = gr.Checkbox(label='Guess Mode', value=False)  
                low_threshold = gr.Slider(label="Canny low threshold", minimum=1, maximum=255, value=100, step=1)  
                high_threshold = gr.Slider(label="Canny high threshold", minimum=1, maximum=255, value=200, step=1)  
                ddim_steps = gr.Slider(label="Steps", minimum=1, maximum=100, value=20, step=1)  
                scale = gr.Slider(label="Guidance Scale", minimum=0.1, maximum=30.0, value=9.0, step=0.1)  
                seed = gr.Slider(label="Seed", minimum=-1, maximum=2147483647, step=1, randomize=True)  
                eta = gr.Number(label="eta (DDIM)", value=0.0)  
                a_prompt = gr.Textbox(label="Added Prompt", value='best quality, extremely detailed')  
                n_prompt = gr.Textbox(label="Negative Prompt",  
                                      value='longbody, lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality')  
        with gr.Column():  
            result_gallery = gr.Gallery(label='Output', show_label=False, elem_id="gallery").style(grid=2, height='auto')  
    ips = [input_image, prompt, a_prompt, n_prompt, num_samples, image_resolution, ddim_steps, guess_mode, strength, scale, seed, eta, low_threshold, high_threshold]  
    run_button.click(fn=process, inputs=ips, outputs=[result_gallery])  
  
  
block.launch(server_name='0.0.0.0')

其他的模型,比如gradio\_hed2image.py,它可以保留输入图像中的许多细节,适合图像的重新着色和样式化的场景:

还记得AnimeGANv2模型吗:神工鬼斧惟肖惟妙,M1 mac系统深度学习框架Pytorch的二次元动漫动画风格迁移滤镜AnimeGANv2+Ffmpeg(图片+视频)快速实践,之前还只能通过统一模型滤镜进行转化,现在只要修改引导词,我们就可以肆意地变化出不同的滤镜,人工智能技术的发展,就像发情的海,汹涌澎湃。

结语

“人类嘛时候会被人工智能替代呀?”

“就是现在!就在今天!”

就算是达芬奇还魂,齐白石再生,他们也会被现今的人工智能AI技术所震撼,纵横恣肆的笔墨,抑扬变化的形态,左右跌宕的心气,焕然飞动的神采!历史长河中这一刻,大千世界里这一处,让我们变得疯狂!

最后奉上修改后的基于Python3.10的Cpu训练版本的ControlNet,与众亲同飨:https://github.com/zcxey2911/ControlNet\_py3.10\_cpu\_NoConda

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
5天前
|
人工智能 API 语音技术
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
TEN Agent 是一个开源的实时多模态 AI 代理框架,集成了 OpenAI Realtime API 和 RTC 技术,支持语音、文本和图像的多模态交互,具备实时通信、模块化设计和多语言支持等功能,适用于智能客服、实时语音助手等多种场景。
67 15
TEN Agent:开源的实时多模态 AI 代理框架,支持语音、文本和图像的实时通信交互
|
7天前
|
消息中间件 人工智能 运维
12月更文特别场——寻找用云高手,分享云&AI实践
我们寻找你,用云高手,欢迎分享你的真知灼见!
659 43
|
8天前
|
机器学习/深度学习 人工智能
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
SNOOPI是一个创新的AI文本到图像生成框架,通过增强单步扩散模型的指导,显著提升模型性能和控制力。该框架包括PG-SB和NASA两种技术,分别用于增强训练稳定性和整合负面提示。SNOOPI在多个评估指标上超越基线模型,尤其在HPSv2得分达到31.08,成为单步扩散模型的新标杆。
48 10
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
|
8天前
|
人工智能 搜索推荐 开发者
Aurora:xAI 为 Grok AI 推出新的图像生成模型,xAI Premium 用户可无限制访问
Aurora是xAI为Grok AI助手推出的新图像生成模型,专注于生成高逼真度的图像,特别是在人物和风景图像方面。该模型支持文本到图像的生成,并能处理包括公共人物和版权形象在内的多种图像生成请求。Aurora的可用性因用户等级而异,免费用户每天能生成三张图像,而Premium用户则可享受无限制访问。
46 11
Aurora:xAI 为 Grok AI 推出新的图像生成模型,xAI Premium 用户可无限制访问
|
6天前
|
人工智能 缓存 异构计算
云原生AI加速生成式人工智能应用的部署构建
本文探讨了云原生技术背景下,尤其是Kubernetes和容器技术的发展,对模型推理服务带来的挑战与优化策略。文中详细介绍了Knative的弹性扩展机制,包括HPA和CronHPA,以及针对传统弹性扩展“滞后”问题提出的AHPA(高级弹性预测)。此外,文章重点介绍了Fluid项目,它通过分布式缓存优化了模型加载的I/O操作,显著缩短了推理服务的冷启动时间,特别是在处理大规模并发请求时表现出色。通过实际案例,展示了Fluid在vLLM和Qwen模型推理中的应用效果,证明了其在提高模型推理效率和响应速度方面的优势。
云原生AI加速生成式人工智能应用的部署构建
|
4天前
|
机器学习/深度学习 人工智能 监控
AI视频监控技术的核心优势与实践
AI视频监控技术结合了计算机视觉、深度学习和大数据分析,能够实时分析监控画面,识别异常行为和场景变化。其核心在于从“被动记录”转型为“主动识别”,提升监控效率并减少安全隐患。主要应用场景包括泳池管理、健身器械区域、人员密度预警和异常事件检测。系统架构支持多种摄像头设备,采用边缘计算和Docker部署,具备实时性、高准确率和扩展性等优势。未来将优化复杂场景适应性和实时计算负载,进一步提高系统性能。
|
6天前
|
人工智能 Cloud Native 调度
阿里云容器服务在AI智算场景的创新与实践
本文源自张凯在2024云栖大会的演讲,介绍了阿里云容器服务在AI智算领域的创新与实践。从2018年推出首个开源GPU容器共享调度方案至今,阿里云容器服务不断推进云原生AI的发展,包括增强GPU可观测性、实现多集群跨地域统一调度、优化大模型推理引擎部署、提供灵活的弹性伸缩策略等,旨在为客户提供高效、低成本的云原生AI解决方案。
|
11天前
|
人工智能
带上团队一起来做 AI 编程实践丨通义灵码联合TGO鲲鹏会开启 AI 大课
带上团队一起来做 AI 编程实践丨通义灵码联合TGO鲲鹏会开启 AI 大课
|
12天前
|
人工智能 运维 自然语言处理
智能化运维:AI在IT运维领域的深度应用与实践####
本文探讨了人工智能(AI)技术在IT运维领域的深度融合与实践应用,通过分析AI驱动的自动化监控、故障预测与诊断、容量规划及智能决策支持等关键方面,揭示了AI如何赋能IT运维,提升效率、降低成本并增强系统稳定性。文章旨在为读者提供一个关于AI在现代IT运维中应用的全面视角,展示其实际价值与未来发展趋势。 ####
76 4
|
12天前
|
机器学习/深度学习 人工智能 数据挖掘
AI精通Python365天第1课,揭秘难易度
学习Python能显著提升就业竞争力,实现工作自动化,增强数据分析、机器学习、Web开发等技能,促进跨领域应用和个人成长。无论是职场新人还是资深人士,掌握Python都能带来正向的职业发展和收入增长,同时回馈社会。通过AI辅助学习Python,从基础代码开始实践,逐步提升编程能力,让技术成为个人发展的强大助力。
23 1