八十行代码实现开源的 Midjourney、Stable Diffusion “咒语”作图工具
本篇文章聊聊如何通过 Docker 和八十行左右的 Python 代码,实现一款类似 Midjourney 官方图片解析功能 Describe 的 Prompt 工具。
让你在玩 Midjourney、Stable Diffusion 这类模型时,不再为生成 Prompt 描述挠头。
写在前面
本文将提供两个版本的工具,分别支持 CPU 和 GPU 推理使用,如果你有一张大于 8GB 显存的显卡,可以愉快的使用全部的功能,如果你只有 CPU,那么也可以使用 CPU 版本的应用来进行偷懒。
本篇文章的代码已上传至 GitHub soulteary/docker-prompt-generator,欢迎自取,以及“一键三连”。
昨晚在玩 Midjourney 的时候,在想 Prompt 的时候,想到挠头。作为一个懒人,计上心头:能不能让模型帮我生成 Prompt 呢,输入一些关键词或者句子,然后让程序帮助我完成完整的 Prompt 内容。(俗话:文生文)于是我开了个坑,创建了上面的这个开源项目,在简单验证可行性之后,就去补觉了。
一觉起来,看到有着相同兴趣爱好的同事转发了一篇文章:Midjourney 发布了新功能,“describe”,支持解析图片为几段不同的 Prompt 文本,并支持继续进行图片生成。(俗话:图生文,然后文生图)
这个功能相比昨晚折腾的小东西,显然更能体现先进的生产效率嘛(作为懒人体验非常好)。
可惜网上扫了一圈,发现官方功能并不开源,那么,我来实现一个吧。
“作图咒语生成器” 的使用
为了更快的上手和使用到这个工具,我们需要先完成环境的配置。
应用和 Docker 环境准备
在过去的几篇文章里,我提到过了我个人习惯和推荐的开发环境,基于 Docker 和 Nvidia 官方基础容器的深度学习环境,所以就不再赘述相关知识点,感兴趣可以自行翻阅,比如这篇《基于 Docker 的深度学习环境:入门篇》。相信老读者应该已经很熟悉啦。
当然,因为本文包含纯 CPU 也能玩的部分,你也可以参考几个月前的《在搭载 M1 及 M2 芯片 MacBook设备上玩 Stable Diffusion 模型》,来配置你的环境。
在准备好 Docker 环境的配置之后,我们就可以继续玩啦。
我们随便找一个合适的目录,使用 git clone
或者下载 Zip 压缩包的方式,先把“Docker Prompt Generator(Docker 作图咒语生成器)”项目的代码下载到本地。
git clone https://github.com/soulteary/docker-prompt-generator.git
# or
curl -sL -o docker-prompt-generator.zip https://github.com/soulteary/docker-prompt-generator/archive/refs/heads/main.zip
接着,进入项目目录,使用 Nvidia 原厂的 PyTorch Docker 基础镜像来完成基础环境的构建,相比于我们直接从 DockerHub 拉制作好的镜像,自行构建将能节约大量时间。
我们在项目目录中执行下面的命令,就能够完成应用模型应用的构建啦:
# 构建基础镜像
docker build -t soulteary/prompt-generator:base . -f docker/Dockerfile.base# 构建 CPU 应用
docker build -t soulteary/prompt-generator:cpu . -f docker/Dockerfile.cpu# 构建 GPU 应用
docker build -t soulteary/prompt-generator:gpu . -f docker/Dockerfile.gpu
然后,根据你的硬件环境,选择性执行下面的命令,就能够启动一个带有 Web UI 界面的模型应用啦。
# 运行 CPU 镜像
docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -p 7860:7860 soulteary/prompt-generator:cpu# 运行 GPU 镜像
docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -p 7860:7860 soulteary/prompt-generator:gpu
我们在浏览器中输入运行容器的宿主机的 IP 地址,就能够开始使用工具啦。
使用工具
工具的使用,非常简单,分别有使用“图片生成描述”和使用“文本生成描述”两种。
我找了一张之前模型生成的图片,然后将这张图片喂给这个程序,点击按钮,就能获得图片的描述文本啦。
我们可以在 Midjourney 或者 Stable Diffusion 中,直接使用这段文本来继续生成图片,或者使用“从文本中生成”,来扩展内容,让内容更适合 Midjourney 这类应用。
为了体现工具的中文翻译和续写能力,我们单独写一段简单的中文描述:“一只小鸟立梢头,一轮明月当空照,一片黄叶铺枝头”。
可以看到,基于我们的输入内容,生成了非常多不同的文本。
想要验证文本内容是否符合原意,我们可以将内容粘贴到 Midjourney 中进行测试。
因为模型存在随机性,如果想要得到更好的结果,还需要对描述进行更多的调整优化,不过,看起来工具解析图片,生成的描述,其实是能够做到开箱即用的,而根据我们的三言两语生成的文本,也生成出了符合要求的图片。
好啦,工具的基础使用,我们介绍完啦。
模型应用功能实现
下面是工具的实现流程和思考,如果你想学习或快速使用开源模型项目来构建你的 AI 容器应用,可以继续浏览。
应用功能设计
在“动手”前,我们需要先明确功能设计,以及考虑使用什么样的技术来做具体功能的技术支撑。
在我日常使用 Stable Diffusion、Midjourney 的过程中,时常有三个场景挠头:
- 我只有一些关键词,需要发挥想象力把关键词串起来,然后喂给模型应用。如果描述内容不够好,或者关键词之间的关联比较远,那么图片的生成效果就不会特别好。
- 我有一张图片,想让模型围绕图片中的内容,比如:构图、某些元素、情感等进行二次创作,而不是简单的做图片中的元素替换。
- 我更习惯使用中文做描述,而不是英文,但是目前模型生成图片,想要好的效果,需要使用英文,总是借助翻译工具,切换程序界面或者网页,还是挺麻烦的。
解决第一个问题,我们可以使用最近火爆出圈的 GPT-4 的前辈的前辈:GPT-2 其实就能够满足需求,将内容(一句话、几个关键词)进行快速续写。相比较使用 GPT-3 / GPT-4,无需联网,也无需付费,模型文件更是“便宜大碗”,用 CPU 就能跑起来。
解决第二个问题,我们可以使用 OpenAI 在一年前推出的 CLIP 神经网络模型,以及 Salesforce 推出的 BLIP ,能够从图片中抽取出最合适的描述文本,让我们用在新的 AIGC 图片生成任务中。稍作优化调整,我们只需要大概使用 6~8GB 显存就能将这部分功能的模型跑起来。
解决第三个问题,我们可以使用赫尔辛基大学开源的 OPUS MT 模型,实现将中文翻译为英文,进一步偷懒,以及解决上面两类原始模型不支持中文输入的问题。
因为前两个场景问题中的模型不支持中文,而我又是一个懒人,不想输入英文来玩图,所以我们先来解决第三个问题,让整个应用实现流程更丝滑。
中文 Prompt 翻译为英文 Prompt 功能
想要实现第一个懒人功能,从用户输入的中文内容中,自动生成英文,我们需要使用中英双语的翻译模型。赫尔辛基大学的开源组织将预训练模型开放在了 HuggingFace 社区,Helsinki-NLP/opus-mt-zh-en。
我们可以通过写十五行简单的 Python 代码,来完成模型文件的下载,以及实现将中文自动转换为合适的英文内容的功能。比如下面的例子中,程序运行完毕,将输出《火影忍者》中的金句“青春不能回头,所以青春没有终点”的译文。
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import torchmodel = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-zh-en").eval()
tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-zh-en")def translate(text):with torch.no_grad():encoded = tokenizer([text], return_tensors="pt")sequences = model.generate(**encoded)return tokenizer.batch_decode(sequences, skip_special_tokens=True)[0]input = "青春不能回头,所以青春没有终点。 ——《火影忍者》"
print(input, translate(input))
将上面的代码保存为 translate.py
,然后执行 python translate.py
,等待模型下载完毕,我们将得到类似下面的结果:
青春不能回头,所以青春没有终点。 Youth can't turn back, so there's no end to youth.
是不是看起来还不错?这部分代码保存在了项目中的 soulteary/docker-prompt-generator/app/translate.py。
接下来,我们来实现 Prompt “免费续杯”(有逻辑续写)功能。
实现 MidJourney Prompt 续写功能
基于一些内容,进行继续的内容生成,是生成类模型的看家本领,比如大家已经熟悉的不能再熟悉的 ChatGPT 背后的 GPT 模型系列。
作为一个懒人,我在网上寻觅了一番,找到了一个 Google 离职创业的“国外大姐” 基于 GPT-2 使用 25 万条 MidJourney 数据 fine-tune 好的 GPT2 模型:succinctly/text2image-prompt-generator,简单试了试了试效果还不错,那么我们就用它来实现这部分功能吧。(其实,用前几篇文章里的 LLaMA 也行,可以自行替换。)
和上面一样,我们实现一个不到 30 行的简单的程序,就能够实现模型自动下载,以及调用模型根据我们的输入内容(上文中热血台词的翻译)生成一些符合 Midjourney 或 Stable Diffusion 的新的 Prompt 内容:
from transformers import pipeline, set_seed
import random
import retext_pipe = pipeline('text-generation', model='succinctly/text2image-prompt-generator')def text_generate(input):seed = random.randint(100, 1000000)set_seed(seed)for count in range(6): sequences = text_pipe(input, max_length=random.randint(60, 90), num_return_sequences=8)list = []for sequence in sequences:line = sequence['generated_text'].strip()if line != input and len(line) > (len(input) + 4) and line.endswith((":", "-", "—")) is False:list.append(line)result = "\n".join(list)result = re.sub('[^ ]+\.[^ ]+','', result)result = result.replace("<", "").replace(">", "")if result != "":return resultif count == 5:return resultinput = "Youth can't turn back, so there's no end to youth."
print(input, text_generate(input))
我们将上面的代码保存为 text-generation.py
,然后执行 python text-generation.py
,稍等片刻我们将得到类似下面的内容:
# Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.
Youth can't turn back, so there's no end to youth. Youth can't turn back, so there's no end to youth. Young, handsome, confident, lonely boy sitting on his can't turn back, so there's no end to youth. Where old yang waits, young man on the streets of Bangkok::10 film poster::10 photorealism, postprocessing, low angle::10 Trending on artstation::8 —ar 47:82
Youth can't turn back, so there's no end to youth. By Karel Thole and Mike Mignola --ar 2:3
Youth can't turn back, so there's no end to youth. And there is a bright hope about a future where there will be time.
内容看起来好像还不错,我们直接在 Midjourney 中输入测试,将得到类似下面的结果。
看起来算是及格了,这部分代码保存在项目的 soulteary/docker-prompt-generator/app/text-generation.py中,有需要可以自取。
完成了两个功能之后,我们来实现根据图片内容生成 Prompt 描述的应用功能。
实现根据图片生成 Prompt 描述功能
相比较上面两个功能,使用 CPU 就能搞定,内容生成效率也非常高。
但是想要快速的根据图片生成 Prompt 则需要显卡的支持。不过根据我的试验,运行起来只需要 6~8GB 左右的显存,还是比较省钱的。(没有显卡可以使用云服务器代替,买个按量的,玩罢销毁即可。)
这里,我们依旧是实现一段简单的,不到 30 行的 Python 代码,完成模型下载、应用加载、图片下载,以及将图片转换为 Prompt 的功能:
from clip_interrogator import Config, Interrogator
import torch
config = Config()
config.device = 'cuda' if torch.cuda.is_available() else 'cpu'
config.blip_offload = False if torch.cuda.is_available() else True
config.chunk_size = 2048
config.flavor_intermediate_count = 512
config.blip_num_beams = 64
config.clip_model_name = "ViT-H-14/laion2b_s32b_b79k"
ci = Interrogator(config)def get_prompt_from_image(image):return ci.interrogate(image.convert('RGB'))import requests
import shutil
r = requests.get("https://pic1.zhimg.com/v2-6e056c49362bff9af1eb39ce530ac0c6_1440w.jpg?source=d16d100b", stream=True)
if r.status_code == 200:with open('./image.jpg', 'wb') as f:r.raw.decode_content = Trueshutil.copyfileobj(r.raw, f) from PIL import Image
print(get_prompt_from_image(Image.open('./image.jpg')))
代码中的图片,使用了我专栏中上一篇文章的题图(同样使用 Midjourney 生成)。将上面的内容保存为 clip.py
,然后执行 python clip.py
,稍等片刻,我们将得到类似下面的结果:
# WARNING:root:Pytorch pre-release version 1.14.0a0+410ce96 - assuming intent to test it
Loading BLIP model...
load checkpoint from https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_large_caption.pth
Loading CLIP model...
Loaded CLIP model and data in 8.29 seconds.
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 55/55 [00:00<00:00, 316.23it/s]
Flavor chain: 38%|███████████████████████████████████████████████████████▏ | 12/32 [00:04<00:07, 2.74it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 55/55 [00:00<00:00, 441.49it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6/6 [00:00<00:00, 346.74it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [00:00<00:00, 457.84it/s]a robot with a speech bubble on a blue background, highly detailed hyper real retro, artificial intelligence!!, toy photography, by Emma Andijewska, markings on robot, computer generated, blueish, delete, small gadget, animated, blue body, in retro colors
从结果中看,描述还是比较准确的。这部分代码我保存在了项目的 soulteary/docker-midjourney-prompt-generator/app/clip.py。
好啦,到目前为止,三个主要功能,我们就都实现完毕了。接下来,我们借助 Docker 和 Gradio 来完成 Web UI 和一键运行的模型容器应用。
使用 Docker 构建 AI 应用容器
接下来,我们来完成 AI 应用的容器构建和相关代码编写。
前文中提到,我们将实现两个版本的应用,分别支持 CPU 和 GPU 来完成快速的 AI 模型推理功能。因为后者可以向下兼容前者,所以我们先来实现一个包含前两个应用功能,CPU 就能跑的模型基础镜像。
完成只需要 CPU 运行的应用容器镜像
结合上文中的代码,Dockerfile 文件不难编写:
FROM nvcr.io/nvidia/pytorch:22.12-py3
LABEL org.opencontainers.image.authors="soulteary@gmail.com"RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \pip install transformers sentencepiece sacremoses && \pip install gradioWORKDIR /appRUN cat > /get-models.py <<EOF
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline
AutoModelForSeq2SeqLM.from_pretrained('Helsinki-NLP/opus-mt-zh-en')
AutoTokenizer.from_pretrained('Helsinki-NLP/opus-mt-zh-en')
pipeline('text-generation', model='succinctly/text2image-prompt-generator')
EOFRUN python /get-models.py && \rm -rf /get-models.py
将上面的内容保存为 Dockerfile.base
,然后使用 docker build -t soulteary/prompt-generator:base . -f Dockerfile.base
,稍等片刻,包含了模型文件的基础应用模型就搞定啦。
[+] Building 189.5s (7/8) => [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [internal] load build definition from Dockerfile.base 0.0s=> => transferring dockerfile: 692B 0.0s=> [internal] load metadata for nvcr.io/nvidia/pytorch:22.12-py3 0.0s=> [1/5] FROM nvcr.io/nvidia/pytorch:22.12-py3 0.0s=> CACHED [2/5] RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && pip install transformers sentencepiece sacremoses && pip install gradio 0.0s=> CACHED [3/5] WORKDIR /app 0.0s=> CACHED [4/5] RUN cat > /get-models.py <<EOF 0.0s=> [5/5] RUN python /get-models.py && rm -rf /get-models.py 189.4s=> => # Downloading (…)olve/main/source.spm: 100%|██████████| 805k/805k [00:06<00:00, 130kB/s] => => # Downloading (…)olve/main/target.spm: 100%|██████████| 807k/807k [00:01<00:00, 440kB/s] => => # Downloading (…)olve/main/vocab.json: 100%|██████████| 1.62M/1.62M [00:01<00:00, 1.21MB/s] => => # Downloading (…)lve/main/config.json: 100%|██████████| 907/907 [00:00<00:00, 499kB/s] => => # Downloading pytorch_model.bin: 100%|██████████| 665M/665M [00:11<00:00, 57.2MB/s] => => # Downloading (…)okenizer_config.json: 100%|██████████| 255/255 [00:00<00:00, 81.9kB/s]
实现过程中,我这边的构建时间大概要 5 分钟左右,可以从椅子上起来,动一动,听首歌放松一会。
镜像构建完毕,可以使用下面的命令,进入包含模型和 PyTorch 环境的 Docker 镜像。在这个镜像中,我们可以自由的使用前两个功能相关的模型:
docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -p 7680:7680 soulteary/prompt-generator:base bash
有了环境之后,我们来继续实现一个简单的 Web UI,实现上文中的懒人功能:让模型根据我们输入的中文内容,生成可以绘制高质量图片的 Prompt:
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import torchmodel = AutoModelForSeq2SeqLM.from_pretrained('Helsinki-NLP/opus-mt-zh-en').eval()
tokenizer = AutoTokenizer.from_pretrained('Helsinki-NLP/opus-mt-zh-en')def translate(text):with torch.no_grad():encoded = tokenizer([text], return_tensors='pt')sequences = model.generate(**encoded)return tokenizer.batch_decode(sequences, skip_special_tokens=True)[0]from transformers import pipeline, set_seed
import random
import retext_pipe = pipeline('text-generation', model='succinctly/text2image-prompt-generator')def text_generate(input):seed = random.randint(100, 1000000)set_seed(seed)text_in_english = translate(input)for count in range(6): sequences = text_pipe(text_in_english, max_length=random.randint(60, 90), num_return_sequences=8)list = []for sequence in sequences:line = sequence['generated_text'].strip()if line != text_in_english and len(line) > (len(text_in_english) + 4) and line.endswith((':', '-', '—')) is False:list.append(line)result = "\n".join(list)result = re.sub('[^ ]+\.[^ ]+','', result)result = result.replace('<', '').replace('>', '')if result != '':return resultif count == 5:return resultimport gradio as grwith gr.Blocks() as block:with gr.Column():with gr.Tab('文本生成'):input = gr.Textbox(lines=6, label='你的想法', placeholder='在此输入内容...')output = gr.Textbox(lines=6, label='生成的 Prompt')submit_btn = gr.Button('快给我编')submit_btn.click(fn=text_generate,inputs=input,outputs=output)block.queue(max_size=64).launch(show_api=False, enable_queue=True, debug=True, share=False, server_name='0.0.0.0')
在容器环境中创建一个名为 webui.cpu.py
的文件,然后使用 python webui.cpu.py
,将看到类似下面的日志输出:
Running on local URL: http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
然后我们在浏览器中打开容器所在设备的 IP (如果在本机运行,可以访问 http://127.0.0.1:7860
,就能访问 Web 服务啦。
我们在上面的输入框里输入一些内容,然后点击“快给我编”按钮,就能够得到一堆模型编出来的 Prompt 内容啦。
实现完“文生文”功能之后,我们来实现“图生文”相关功能。
完成需要 GPU 运行的应用容器镜像
结合上文,完成 GPU 相关功能需要的容器环境也不难:
FROM soulteary/prompt-generator:base
LABEL org.opencontainers.image.authors="soulteary@gmail.com"RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \pip install clip_interrogator git+https://github.com/pharmapsychotic/BLIP.git@lib#egg=blipRUN cat > /get-models.py <<EOF
from clip_interrogator import Config, Interrogator
import torch
config = Config()
config.device = 'cuda' if torch.cuda.is_available() else 'cpu'
config.blip_offload = False if torch.cuda.is_available() else True
config.chunk_size = 2048
config.flavor_intermediate_count = 512
config.blip_num_beams = 64
config.clip_model_name = "ViT-H-14/laion2b_s32b_b79k"
ci = Interrogator(config)
EOFRUN python /get-models.py && \rm -rf /get-models.py
将上面的内容保存为 Dockerfile.gpu
文件,然后使用 docker build -t soulteary/prompt-generator:gpu . -f Dockerfile.gpu
完成镜像的构建。
耐心等待镜像构建完毕,使用下面的命令,能够进入包含三种模型和 PyTorch 环境的 Docker 镜像:
docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -p 7680:7680 soulteary/prompt-generator:gpu bash
接着,来编写能够调用三种模型能力的 Python 程序:
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import torchmodel = AutoModelForSeq2SeqLM.from_pretrained('Helsinki-NLP/opus-mt-zh-en').eval()
tokenizer = AutoTokenizer.from_pretrained('Helsinki-NLP/opus-mt-zh-en')def translate(text):with torch.no_grad():encoded = tokenizer([text], return_tensors='pt')sequences = model.generate(**encoded)return tokenizer.batch_decode(sequences, skip_special_tokens=True)[0]from transformers import pipeline, set_seed
import random
import retext_pipe = pipeline('text-generation', model='succinctly/text2image-prompt-generator')def text_generate(input):seed = random.randint(100, 1000000)set_seed(seed)text_in_english = translate(input)for count in range(6): sequences = text_pipe(text_in_english, max_length=random.randint(60, 90), num_return_sequences=8)list = []for sequence in sequences:line = sequence['generated_text'].strip()if line != text_in_english and len(line) > (len(text_in_english) + 4) and line.endswith((':', '-', '—')) is False:list.append(line)result = "\n".join(list)result = re.sub('[^ ]+\.[^ ]+','', result)result = result.replace('<', '').replace('>', '')if result != '':return resultif count == 5:return resultfrom clip_interrogator import Config, Interrogator
import torch
import gradio as grconfig = Config()
config.device = 'cuda' if torch.cuda.is_available() else 'cpu'
config.blip_offload = False if torch.cuda.is_available() else True
config.chunk_size = 2048
config.flavor_intermediate_count = 512
config.blip_num_beams = 64
config.clip_model_name = "ViT-H-14/laion2b_s32b_b79k"ci = Interrogator(config)def get_prompt_from_image(image, mode):image = image.convert('RGB')if mode == 'best':prompt = ci.interrogate(image)elif mode == 'classic':prompt = ci.interrogate_classic(image)elif mode == 'fast':prompt = ci.interrogate_fast(image)elif mode == 'negative':prompt = ci.interrogate_negative(image)return promptwith gr.Blocks() as block:with gr.Column():gr.HTML('<h1>MidJourney / SD2 懒人工具</h1>')with gr.Tab('从图片中生成'):with gr.Row():input_image = gr.Image(type='pil')with gr.Column():input_mode = gr.Radio(['best', 'fast', 'classic', 'negative'], value='best', label='Mode')img_btn = gr.Button('这图里有啥')output_image = gr.Textbox(lines=6, label='生成的 Prompt')with gr.Tab('从文本中生成'):input_text = gr.Textbox(lines=6, label='你的想法', placeholder='在此输入内容...')output_text = gr.Textbox(lines=6, label='生成的 Prompt')text_btn = gr.Button('快给我编')img_btn.click(fn=get_prompt_from_image, inputs=[input_image, input_mode], outputs=output_image)text_btn.click(fn=text_generate, inputs=input_text, outputs=output_text)block.queue(max_size=64).launch(show_api=False, enable_queue=True, debug=True, share=False, server_name='0.0.0.0')
我们将上面的程序保存为 webui.gpu.py
,然后使用 python webui.gpu.py
运行程序,将得到类似下面的日志:
██████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44.0/44.0 [00:00<00:00, 31.5kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 786k/786k [00:01<00:00, 772kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 788k/788k [00:00<00:00, 863kB/s]
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.54M/1.54M [00:01<00:00, 1.29MB/s]
Downloading: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 907/907 [00:00<00:00, 618kB/s]
Downloading: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 634M/634M [00:27<00:00, 23.8MB/s]
Downloading: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 255/255 [00:00<00:00, 172kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 779k/779k [00:01<00:00, 757kB/s]
Downloading: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 446k/446k [00:00<00:00, 556kB/s]
Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2.01M/2.01M [00:01<00:00, 1.60MB/s]
Downloading: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 99.0/99.0 [00:00<00:00, 69.2kB/s]
I0405 12:50:42.798199 140240289830720 instantiator.py:21] Created a temporary directory at /tmp/tmpuvpi8s9q
I0405 12:50:42.798363 140240289830720 instantiator.py:76] Writing /tmp/tmpuvpi8s9q/_remote_module_non_scriptable.py
W0405 12:50:42.878760 140240289830720 version.py:27] Pytorch pre-release version 1.14.0a0+410ce96 - assuming intent to test it
I0405 12:50:43.373221 140240289830720 font_manager.py:1633] generated new fontManager
Loading BLIP model...
load checkpoint from https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_large_caption.pth
Loading CLIP model...
I0405 12:51:00.455630 140240289830720 factory.py:158] Loaded ViT-H-14 model config.
I0405 12:51:06.642275 140240289830720 factory.py:206] Loading pretrained ViT-H-14 weights (laion2b_s32b_b79k).
Loaded CLIP model and data in 8.22 seconds.
Running on local URL: http://0.0.0.0:7860To create a public link, set `share=True` in `launch()`.
当看到 Running on local URL: http://0.0.0.0:7860
的日志的时候,我们就可以在浏览器中访问程序啦。
将上文中的图片投喂给它,然后点下“这图里有啥”按钮,稍等片刻,我们将得到一些比较合理的 Prompts 内容,你可以用这些内容去生成图片。
当然,你也可以将生成的文本内容再投喂给它,来获得更多的 Prompt 内容,让图片的变化更丰富一些。
其他:显存资源消耗
在模型识别图片的过程中,我简单记录了应用的显存消耗,峰值大概在 8GB 左右。
Wed Apr 5 21:00:09 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.89.02 Driver Version: 525.89.02 CUDA Version: 12.0 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 Off | Off |
| 31% 35C P8 23W / 450W | 8111MiB / 24564MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------++-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 1286 G /usr/lib/xorg/Xorg 9MiB |
| 0 N/A N/A 1504 G /usr/bin/gnome-shell 10MiB |
| 0 N/A N/A 115252 C python 8086MiB |
+-----------------------------------------------------------------------------+
最后
好了,这篇文章就先聊到这里啦。
下一篇文章,或许该揭示之前 fine-tune 的大模型的效果啦,最近一直很忙,直到今天才有空折腾模型。
–EOF
我们有一个小小的折腾群,里面聚集了一些喜欢折腾的小伙伴。
在不发广告的情况下,我们在里面会一起聊聊软硬件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术资料。
喜欢折腾的小伙伴,欢迎阅读下面的内容,扫码添加好友。
关于“交友”的一些建议和看法
添加好友时,请备注实名和公司或学校、注明来源和目的,否则不会通过审核。
关于折腾群入群的那些事
本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)
本文作者: 苏洋
创建时间: 2023年04月05日
统计字数: 10422字
阅读时间: 21分钟阅读
本文链接: https://soulteary.com/2023/04/05/eighty-lines-of-code-to-implement-the-open-source-midjourney-and-stable-diffusion-spell-drawing-tool.html
相关文章:

八十行代码实现开源的 Midjourney、Stable Diffusion “咒语”作图工具
本篇文章聊聊如何通过 Docker 和八十行左右的 Python 代码,实现一款类似 Midjourney 官方图片解析功能 Describe 的 Prompt 工具。 让你在玩 Midjourney、Stable Diffusion 这类模型时,不再为生成 Prompt 描述挠头。 写在前面 本文将提供两个版本的工…...
Redis为什么这么快
RedisRedis为什么这么快基于内存单线程实现(Redis 6.0 以前)IO多路复用模型高效的数据结构Redis为何选择单线程Redis的应用场景Redis怎么实现消息队列Redis的主从复制原理主从复制的原理过期键的删除策略Redis为什么这么快 基于内存 Redis是使用内存存…...
JayDeBeApi对数据类型的支持
JayDeBeApi对数据类型的支持 常用的数据类型如下: 字符类型 内置字符类型包括:char, nchar, varchar, nvarchar 和lvarchar CHARACTER(n) 和 CHARACTER VARYING(n)这样的别名同样支持 参考代码:test_string_type.py create ""&…...

一文盘点 Zebec 生态几大利好,让 ZBC 近期“狂飙”
近期,ZBC通证迎来了新一轮上涨趋势,我们看到其从3月11日左右的低点$0.0115上涨至$0.0175,这也是近期的最大涨幅之一。我们看到,推动ZBC上涨的主要因素,是Zebec生态近期频繁的布局所带来的系列利好推动。 本文将对近期的…...

【数据结构】栈和队列(笔记总结)
👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:数据结构 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&…...
【Java】自定义注解和AOP切面的使用
前言 我们在开发的过程中,一般都需要对方法的入参进行打印,或者Debug调试的时候我们要查看方法入参的参数是否数量和数据正确性。 一般我们需要知道请求的参数、接口路径、请求ip等 但是考虑以后项目上线BUG排查的问题,最好的方式就是使用…...

前后台协议联调拦截器
前后台协议联调&拦截器4,前后台协议联调4.1 环境准备4.2 列表功能4.3 添加功能4.4 添加功能状态处理4.5 修改功能4.6 删除功能5,拦截器5.1 拦截器概念5.2 拦截器入门案例5.2.1 环境准备5.2.2 拦截器开发步骤1:创建拦截器类步骤2:配置拦截器类步骤3:S…...

【还在传统绑骨骼动画?】让AI助力你实现2D游戏角色动画流程
思路(让3D模型替代动作) 一、利用MJ或者SD生成你需要的游戏角色(获取原图像) 需要的知识: 会调关键词chatGpt(看小红书、抖音、B站、Youtube、Telegrame等等都行,别傻忽忽跑到知识星球被收割…...
动态规划+例题
适用场景 题目链接:数字三角形 /*正推DP,可能数据比较小,这个正推不太麻烦可以AC*/ #include<bits/stdc.h> using namespace std; int r; int a[1005][1005],f[1005][1005];int main(){cin>>r;for(int i1;i<r;i){for(int j1…...

快商通荣获多个政府科技、人才奖项
近日,快商通与快商通首席科学家李海洲教授荣获由厦门市科学技术局、厦门市委人才办等多部门发布的“2022年度厦门市科学技术奖”、“2022厦门十大成长性人才企业”、“2022厦门战略性新兴产业十大创新人才”等多个 政府科技、人才奖项 ,并进行全网公示。…...

Linux的基本命令的使用
文章目录一、初识LinuxLinux目录结构二、如何拥有一个Linux环境?三、Linux命名Linux命令基础lscd pwd特殊路径符clearmkdirtouch cat morecp mv rmsuwhich findgrep wc 管道符ehco tail 重定向符psnetstatvi vim一、初识Linux 我们的计算机由硬件和软件两部分组成&…...
RecycleView小结
RecycleView四级缓存 一级缓存:用于存放当前屏幕可显示区域的ViewHolder,目的是为了方便更新数据,以及对View操作时更加快捷二级缓存:用于缓存最近滑动出屏幕的ViewHolder,目的是为了当用户将该View滑出屏幕外时又突然…...

【Python】如何实现Redis构造简易客户端(教程在这)
文章目录前言一、准备二、原理剖析三、编写简易Redis客户端总结前言 Redis 是我们在开发过程中经常会用到的内存数据库,尤其是在Python的第三方模块Redis-py的支持下,在Python中使用Redis及其方便。 但是在有些情况下,我们无法使用像Redis-…...

326. 3 的幂 ——【Leetcode每日一题】
326. 3 的幂 给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。 整数 n 是 3 的幂次方需满足:存在整数 x 使得 n3xn 3^xn3x。 示例 1: 输入:n 27 …...

UE4 Sequence学习
1.常用轨道 1.1 Camera轨道 Camera轨道可以理解为Camera Cuts轨道和Camera Actor轨道,一般点击Sequencer上的摄像机图标可以自动创建: Camera Cuts轨道,可以进行不同相机机位的切换,一般会随着Camera Actor轨道自动创建&#x…...

总结MySQL、Redis的优化措施与使用 mysql_upgrade升级数据结构
目录 一.MySQL数据库优化 二.Redis优化 三.MySQL创建测试账号报错 一.MySQL数据库优化 遵循MySQL层优化的五个原则: 减少数据访问,返回更少的数据,减少交互次数减少服务器CPU开销,利用更多资源。理解SQL优化原理并进行SQL优化,…...

C++11线程库
C11线程库 本质是对不同平台的线程库进行封装。因为windows和linux下各有自己的接口,这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行支持了,使得C在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。要使…...

智能化生产,提高效率!使用关键词采集工具助力企业数字化转型
关键词采集工具在企业数字化转型中的优势和作用进行阐述。 随着信息技术的不断发展,企业数字化转型已经成为了企业发展的必然趋势。 对于各种规模的企业而言,数字化转型可以提升企业的生产效率、降低成本、提高产品质量等方面带来更多的发展机遇。 而关…...

浅谈自动化测试用例创建和文档
通过自动创建测试用例和文档,探索自然语言处理 (NLP) 在革新软件测试方面的变革力量。 技术的快速发展导致对高效和有效的软件测试方法的需求增加。该领域最有前途的进步之一是自然语言处理 (NLP) 技术的集成。NLP 是人工智能(AI)的一个子集,专注于通过…...

[Java Web]AJAX Axios | 一种结合HTML来取代传统JSP的技术
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:逐梦苍穹 ⭐所属专栏:Java Web 目录1、AJAX1.1、简介1.2、作用1.3、同步和异步1.4、代码实现1.4.1、服务端1.4.2、客户端1.4.2.1、完善…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...