【python运行Janus-Pro-1B文生图功能】

前言

体验了一把本地部署Janus-Pro-1B实现文生图功能。

1、开源项目下载

官方开源项目代码直接从Github上下载。

在这里插入图片描述

2、模型下载

在这里插入图片描述
模型官方下载需要魔法
Janus-Pro-1B模型文件:Janus-Pro-1B模型文件
百度网盘:
https://pan.baidu.com/s/16t4H4z-QZe2UDAg4EF5g3w?pwd=6666

3、将项目代码和模型添加到同一个文件

1)创建目录存放模型文件

将模型及配置权重文件存放在同一目录下,如Janus-Pro-1B
在这里插入图片描述

2)将模型目录放到官方开源项目中。

在这里插入图片描述

3)创建虚拟环境

使用如下命令创建虚拟环境:

myenv\Scripts\activate

4)安装所需依赖

pip install -r requirements.txt

5) 项目内容如下

在这里插入图片描述

6) 最后运行效果:运行 app_januspro.py

在这里插入图片描述

运行代码

# 导入必要的库
# 用于处理文件和目录路径
# 用于图像处理
# PyTorch库,用于深度学习模型的构建和训练
# 用于数值计算
# Hugging Face的Transformers库,用于加载预训练的语言模型
# 自定义的多模态因果语言模型和处理器
import os  
import PIL.Image  
import time
import torch  
import numpy as np 
from transformers import AutoModelForCausalLM  
from janus.models import MultiModalityCausalLM, VLChatProcessor  
from datetime import datetime # 打印PyTorch版本和CUDA可用性
print(torch.__version__)  
# 打印当前使用的PyTorch版本
print(torch.cuda.is_available())  
# 检查CUDA是否可用(即是否可以使用GPU)# 打印当前GPU的显存占pip install Pillow用情况
print("初始显存占用:", torch.cuda.memory_allocated() / 1024**3, "GB")  # 指定模型路径
# model_path = "deepseek-ai/Janus-Pro-1B"  # 禁用此远程路径
# 使用本地路径
model_path = "./Janus-Pro-1B"  
# 检查模型路径是否存在
assert os.path.exists(model_path), "模型路径不存在!"  
# 打印模型路径
print(f"模型路径:{model_path}")  # 加载VLChatProcessor和tokenizer # 加载VLChatProcessor
vl_chat_processor: VLChatProcessor = VLChatProcessor.from_pretrained(model_path)  # 获取tokenizer,用于将文本编码为模型可以理解的输入格式
tokenizer = vl_chat_processor.tokenizer # 使用AutoModelForCausalLM加载预训练的多模态因果语言模型
vl_gpt: MultiModalityCausalLM = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True
)  
# 将模型转换为float32精度,并将其移动到GPU上,设置为评估模式
vl_gpt = vl_gpt.to(torch.float32).cuda().eval()  # 打印加载模型后的显存占用情况
print("加载模型后显存占用:", torch.cuda.memory_allocated() / 1024**3, "GB") # 定义对话内容
conversation = [{# 用户角色"role": "<|User|>", # 用户输入的文本描述#"content": "long hair,pink lace dress, off-shoulder, high-waist, narrow waist", # "content": "这是一张极简主义的照片,一个橙色的橘子,有绿色的茎和叶,象征着繁荣,在中国新年期间坐在红色的丝绸布上。捕捉一个充满活力的向日葵盛开的特写镜头,一只蜜蜂栖息在它的花瓣上,它精致的翅膀捕捉阳光。",#"content": "这是一张古风照片,一个疑似少年的人站在山顶悬崖边上眺望远处的群山,负手而立,少年周身好似仙人气息,山下烟雾缭绕,隐隐约约有几座宫殿。"#"content":"瓜子脸 + 高额头 + 浓眉 + 大眼睛 + 高鼻梁 + 樱桃小嘴 + 尖下巴 + 白皙皮肤"#"content":"圆脸 + 宽额头 + 细眉 + 小眼睛 + 塌鼻子 + 厚嘴唇 + 圆下巴 + 黝黑皮肤"#"content":"方脸 + 窄额头 + 剑眉 + 丹凤眼 + 鹰钩鼻 + 薄嘴唇 + 方下巴 + 粗糙皮肤""content":"这是一张单独人物的照片、性别男、青年、面无表情、短发刘海、脸部干净、穿着西装、打着领带、脸型圆润、动漫化"},# 助手角色,内容为空{"role": "<|Assistant|>", "content": ""},  
]# 应用SFT模板生成多轮对话的prompt
# 使用VLChatProcessor的apply_sft_template_for_multi_turn_prompts方法将对话内容转换为模型可以理解的格式
sft_format = vl_chat_processor.apply_sft_template_for_multi_turn_prompts(# 对话内容conversations=conversation,# SFT模板格式sft_format=vl_chat_processor.sft_format, # 系统提示,此处为空system_prompt="", 
)  
# 在生成的prompt后添加图像生成的起始标记
prompt = sft_format + vl_chat_processor.image_start_tag  img_size = 384  # 修改图片尺寸384: (1B支持生成最好的尺寸,超过这个会出稀奇古怪的东西)
patch_size = 16  # 假设 patch_size 是 16
image_token_num_per_image = (img_size // patch_size) ** 2  # 计算 token 数量(** 2平方)
# 定义生成函数,用于生成图片
# 使用torch.inference_mode()装饰器,以减少内存占用并加速推理过程
@torch.inference_mode()  
def generate(mmgpt: MultiModalityCausalLM,           # 多模态因果语言模型vl_chat_processor: VLChatProcessor,     # 用于处理输入的处理器prompt: str,                            # 用户输入的文本描述temperature: float = 1,                 # 控制生成过程的随机性parallel_size: int = 1,                 # 一次生成的图片数量cfg_weight: float = 5,                  # 分类器自由引导(Classifier-Free Guidance)的权重image_token_num_per_image=image_token_num_per_image,   # 每张图片生成的token数量 576img_size=img_size,                    # 生成图片的尺寸384patch_size= patch_size,                   # 图片的patch大小
):# 使用tokenizer将prompt编码为input_idsinput_ids = vl_chat_processor.tokenizer.encode(prompt)  # 将input_ids转换为LongTensorinput_ids = torch.LongTensor(input_ids) # 初始化tokens,用于生成图片tokens = torch.zeros((parallel_size * 2, len(input_ids)), dtype=torch.int).cuda()  for i in range(parallel_size * 2):# 将input_ids复制到tokens中tokens[i, :] = input_ids if i % 2 != 0:# 对于非条件tokens,填充pad_idtokens[i, 1:-1] = vl_chat_processor.pad_id  # 获取输入的embeddings  # 将tokens转换为embeddings,作为模型的输入inputs_embeds = mmgpt.language_model.get_input_embeddings()(tokens)  # 初始化生成的tokens  # 初始化用于存储生成图片的tokensgenerated_tokens = torch.zeros((parallel_size, image_token_num_per_image), dtype=torch.int).cuda() # 记录耗时:开始start_time = time.perf_counter()# 逐步生成图片for i in range(image_token_num_per_image):outputs = mmgpt.language_model.model(# 输入的embeddingsinputs_embeds=inputs_embeds, # 使用缓存use_cache=True, # 使用过去的key-valuespast_key_values=outputs.past_key_values if i != 0 else None,  )hidden_states = outputs.last_hidden_state  # 获取隐藏状态# 计算logitslogits = mmgpt.gen_head(hidden_states[:, -1, :]) # 条件logitslogit_cond = logits[0::2, :] # 非条件logitslogit_uncond = logits[1::2, :] #  # 应用分类器自由引导(CFG)权重logits = logit_uncond + cfg_weight * (logit_cond - logit_uncond) # 计算概率分布probs = torch.softmax(logits / temperature, dim=-1)  # 使用torch.multinomial采样下一个tokennext_token = torch.multinomial(probs, num_samples=1) # 将采样的token存储到generated_tokens中generated_tokens[:, i] = next_token.squeeze(dim=-1) # 准备下一个输入的embeddingsnext_token = torch.cat([next_token.unsqueeze(dim=1), next_token.unsqueeze(dim=1)], dim=1).view(-1) # 生成图片的embeddingsimg_embeds = mmgpt.prepare_gen_img_embeds(next_token) # 更新输入的embeddingsinputs_embeds = img_embeds.unsqueeze(dim=1) # 打印每一步的显存占用情况print(f"Step {i}/{image_token_num_per_image} 显存占用:", torch.cuda.memory_allocated() / 1024**3, "GB") # 记录循环结束时间end_time = time.perf_counter()# 计算耗时elapsed_time = end_time - start_timeprint(f"循环耗时: {elapsed_time:.6f} 秒")# 解码生成的tokens为图片dec = mmgpt.gen_vision_model.decode_code(# 生成的tokensgenerated_tokens.to(dtype=torch.int),  # 图片的形状shape=[parallel_size, 8, img_size // patch_size, img_size // patch_size], )# 将生成的图片转换为numpy数组dec = dec.to(torch.float32).cpu().numpy().transpose(0, 2, 3, 1)  # 对图片进行后处理,将其转换为8位无符号整数格式dec = np.clip((dec + 1) / 2 * 255, 0, 255)  # 初始化用于存储最终图片的数组visual_img = np.zeros((parallel_size, img_size, img_size, 3), dtype=np.uint8)  # 将生成的图片存储到visual_img中visual_img[:, :, :] = dec  # 创建目录generated_samplesos.makedirs('generated_samples', exist_ok=True) for i in range(parallel_size):# 获取当前本地时间now = datetime.now()# 格式化输出formatted_time = now.strftime("%Y%m%d%H%M%S%f")# 定义保存路径:生成日期格式save_path = os.path.join('generated_samples', "img_{}.jpg".format(formatted_time)) # 保存生成的图片PIL.Image.fromarray(visual_img[i]).save(save_path)  # 调用生成函数生成图片
generate(# 多模态因果语言模型vl_gpt, # 用于处理输入的处理器vl_chat_processor,  # 用户输入的文本描述prompt, 
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨越时空的对话:图灵与GPT-4聊AI的前世今生

&#xff08;背景&#xff1a;虚拟咖啡厅&#xff0c;图灵身着1950年代西装&#xff0c;端着一杯热茶&#xff0c;GPT-4以全息投影形态坐在对面&#xff09; 图灵&#xff08;喝了口茶&#xff09;&#xff1a;“听说你能写诗&#xff1f;我当年在布莱切利园破解Enigma时&…

L2-4 吉利矩阵

输入样例&#xff1a; 7 3输出样例&#xff1a; 666 这道题是暴力纯搜&#xff0c;但是很难想&#xff0c;我这个是看的别人的代码 #include "bits/stdc.h" using namespace std; int x[20][20]; int l, n; int cnt 0; int sumx[5], sumy[5]; void dfs(int x, in…

Quickwit+Jaeger+Prometheus+Grafana搭建Java日志管理平台

介绍 生产服务应用可观测性在当下比较流行的方案&#xff0c;其中出现了大量高性能、开箱即用、易上手的的开源产品&#xff0c;大大丰富了在可观测性领域产品的多样性&#xff0c;本文讲述基于OTLP协议推送Java项目遥测数据&#xff08;日志、指标、链路&#xff09;到后端存储…

SpringMVC (一)基础

目录 SpringMVC 一 简单使用 1 新建模块选择指定参数 2 创建实现类 3 将项目启动 4 运行结果&#xff1a;在浏览器当中响应执行 二 RequestMapping 三 请求限定 SpringMVC SpringMVC是Spring的web模块&#xff0c;用来开发Web应用&#xff0c;SpringMVC应用最终作为B/…

【机器人-基础知识】欧拉角、旋转矩阵和四元数

1. 欧拉角 1.1. 欧拉角的定义 欧拉角是一组三个角度,用于描述一个刚体在三维空间中的定向关系。具体来说,它们表示从一个固定参考坐标系到刚体坐标系的一系列旋转。常见的定义方式是将总体旋转分解为三个连续的简单旋转,每次旋转都绕着当前坐标系的某一固定轴进行。 例如,…

xxl-job部署在docker-destop,实现定时发送预警信息给指定邮箱

XXL-JOB XXL-JOB是一个分布式任务调度平台&#xff08;XXL是作者徐雪里姓名拼音的首字母&#xff09;&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 源码仓库地址&#xff1a;https://github.com/xuxueli/xxl-job 源码结构&#xff1a; 系统架构 在xxl-j…

大数据学习(63)- Zookeeper详解

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91e; &#x1f…

【数据结构】3顺序表

0 章节 &#xff12;&#xff0e;&#xff11;到&#xff12;&#xff0e;&#xff13;小节。 理解与表达线性表的逻辑结构&#xff1b; 线性表的结构、结构与操作&#xff1b; 顺序表的表示与实现&#xff1b;顺序表应用&#xff1b; 重点 线性表概念、顺序表定义运算与实现&a…

CUDA编程之OpenCV与CUDA结合使用

OpenCV与CUDA的结合使用可显著提升图像处理性能。 一、版本匹配与环境配置 CUDA与OpenCV版本兼容性‌ OpenCV各版本对CUDA的支持存在差异&#xff0c;例如OpenCV 4.5.4需搭配CUDA 10.0‌2&#xff0c;而较新的OpenCV 4.8.0需使用更高版本CUDA‌。 需注意部分模块&#xff08;…

WPF从初学者到专家:实战项目经验分享与总结

WPF从初学者到专家&#xff1a;实战项目经验分享与总结 一、前言二、WPF 基础概念与入门2.1 什么是 WPF2.2 XAML 基础2.3 数据绑定基础 三、第一个 WPF 项目&#xff1a;简单的待办事项列表3.1 项目需求分析3.2 项目搭建与界面设计3.3 业务逻辑实现 四、中级项目&#xff1a;音…

一学就会的深度学习基础指令及操作步骤(3)模型训练验证

文章目录 模型训练验证损失函数和优化器模型优化训练函数验证函数模型保存 模型训练验证 损失函数和优化器 loss_function nn.CrossEntropyLoss() # 损失函数 optimizer Adam(model.parameters()) # 优化器&#xff0c;优化参数模型优化 获得模型所有的可训练参数&#x…

Spring Boot 注解大全:全面解析与实战应用

目录 一、Spring Boot 启动与配置相关注解 1.1 SpringBootApplication 1.2 EnableAutoConfiguration 1.3 Configuration 1.4 ComponentScan 二、依赖注入与组件管理注解 2.1 Component 2.2 Service 2.3 Repository 2.4 Controller 2.5 RestController 2.6 Autowired…

【语料数据爬虫】Python爬虫|批量采集征集意见稿数据(1)

前言 本文是该专栏的第5篇,后面会持续分享Python爬虫采集各种语料数据的的干货知识,值得关注。 在本文中,笔者将主要来介绍基于Python,来实现批量采集“征集意见稿”数据。同时,本文也是采集“征集意见稿”数据系列的第1篇。 采集相关数据的具体细节部分以及详细思路逻辑…

企业招聘能力提升之道:突破困境,精准纳才

企业招聘能力提升之道&#xff1a;突破困境&#xff0c;精准纳才 在企业运营的广袤版图中&#xff0c;招聘工作无疑是一块至关重要的拼图。然而&#xff0c;不少企业在这片领域中举步维艰&#xff0c;尽管投入了海量的时间与精力&#xff0c;收获的成果却不尽人意。面试环节仿…

AI对前端开发的冲击

Cursor cursor新版本0.46版本号中有部分是改成了新布局其实 Agent 和 Edit 和 Composer 是一样的&#xff0c;为了方便大家使用&#xff0c;我们把它们合并了&#xff0c;Edit 相当于普通模式下的 Composer&#xff0c;Agent 就是代理模式。 快捷键ctrli、ctrll、ctrlk 4o适合…

java中如何把json转化的字符串再转化成json格式

使用org.json库 首先&#xff0c;确保你的项目中已经包含了org.json库。如果你使用Maven&#xff0c;可以在pom.xml中添加以下依赖&#xff1a; <dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20210307…

泛型、泛型上限、泛型下限、泛型通配符

DAY8.1 Java核心基础 泛型 Generics 是指在类定义时不指定类中信息的具体数据类型&#xff0c;而是用一个标识符来代替&#xff0c;当外部实例化对象时再指定具体的数据类型。 在定义类或者接口时不明确指定类中信息的具体数据类型&#xff0c;在实例化时再来指定具体的数据类…

Win10 下搭建免费的 FTP 服务器 FileZilla

一、概述 FileZilla 服务器是一个免费的开源FTP和FTPS服务器&#xff0c;是根据GNU通用公共许可证条款免费发布的开源软件。FileZilla支持FTP、FTPS、SFTP等文件传输协议&#xff0c;相比其他FTP服务器&#xff0c;最大的优势是FileZilla自由(免费)。 FileZilla的官网地址是&a…

C/C++中对字符处理的常用函数

C语言中的 ctype.h 头文件提供了一系列字符分类和转换函数&#xff0c;用于高效处理字符相关操作。这些函数通过接受 int 类型参数&#xff08;需为 unsigned char 或 EOF &#xff08;-1&#xff09;值&#xff09;&#xff0c;返回非零值表示条件正确&#xff0c;返回0表示错…

双指针算法介绍+算法练习(2025)

一、介绍双指针算法 双指针&#xff08;或称为双索引&#xff09;算法是一种高效的算法技巧&#xff0c;常用于处理数组或链表等线性数据结构。它通过使用两个指针来遍历数据&#xff0c;从而减少时间复杂度&#xff0c;避免使用嵌套循环。双指针算法在解决诸如查找、排序、去重…