多GPU并行处理[任务分配、进程调度、资源管理、负载均衡]

1. 多GPU并行处理设计
设计思路: 实现基于多GPU的并行任务处理,每个GPU运行独立的任务,以加速整体的处理速度。
实现机制:
进程隔离: 利用multiprocessing.Process为每个GPU创建独立的工作进程。
GPU资源限制: 通过设置CUDA_VISIBLE_DEVICES环境变量,确保每个进程仅能访问其对应的GPU。
任务互斥: 每个GPU拥有一个Lock对象,确保同一时间只有一个任务在特定的GPU上运行。
2. 动态任务分配与负载均衡
设计思路: 通过动态分配任务至队列,实现任务的均匀分布,确保负载均衡。
实现机制:
任务队列: 使用Manager().Queue()创建共享队列,允许多进程安全地存取任务。
设备ID计算: 通过calculate_device_id函数,基于文件路径的哈希值和GPU总数,计算出任务应分配至的GPU,确保任务均匀分配。
3. 进程间通信与同步
设计思路: 确保多进程间的安全通信,避免数据竞争和死锁。
实现机制:
任务获取原子性: 利用Lock对象保护任务获取操作,确保任务获取的原子性。
进程同步: 使用task_queue.join()等待所有任务完成,确保主进程不会在所有子任务完成前退出。
优雅退出: 通过向队列中放置None信号,通知工作进程可以安全退出,实现进程间的优雅终止。
4. 异常处理与资源管理
设计思路: 提供异常处理机制,确保资源的有效管理。
实现机制:
异常捕获: 在worker函数中,使用try-except结构捕获Empty异常,处理队列为空的情况。
资源节约: 通过检查输出文件的存在性,避免重复处理,节省计算资源。
5. 性能优化与监控
设计思路: 优化任务处理流程,提供执行状态的实时反馈。
实现机制:
进度监控: 利用tqdm.write在控制台输出任务执行信息,提供直观的进度反馈。
效率提升: 通过合理的任务分配和进程设计,最大化利用多GPU资源,提升整体处理效率。
总结
该代码的关键设计聚焦于多GPU环境下的并行任务处理,通过精细的进程管理、资源调度、负载均衡策略以及异常处理机制,确保了系统的高效、稳定运行。同时,通过进程间通信和同步机制,以及性能优化措施,进一步提升了系统的整体性能和用户体验。
# 多gpu调度
# python multi_swap_10s_v2.py
import os
import subprocess
from tqdm import tqdm
import hashlib
from multiprocessing import Process, Lock, Manager, Queue
from queue import Empty  # 用于检查队列是否为空# Locks for each GPU to ensure only one task runs at a time per GPU
gpu_locks = [Lock(), Lock()]
# A shared queue for all tasks using Manager's Queue
task_queue = Manager().Queue()def worker(gpu_id, lock):os.environ['CUDA_VISIBLE_DEVICES'] = str(gpu_id)  # Set the CUDA_VISIBLE_DEVICES for this processwhile True:# Try to acquire the lock and get a task atomicallywith lock:try:cmd = task_queue.get_nowait()except Empty:# No more tasks available, exit the workerbreak# Update the progress bar outside the lock to avoid contentiontqdm.write(f"GPU {gpu_id} starting task: {' '.join(cmd)}")# Run the subprocesssubprocess.run(cmd)# Worker finishes when it exits the loopdef calculate_device_id(vid_file, img_file):# Calculate a hash of the file paths to determine the device IDhash_object = hashlib.md5(f"{vid_file}{img_file}".encode())hex_dig = hash_object.hexdigest()return int(hex_dig, 16) % len(gpu_locks)def main():source_videos_dir = "/home/nvidia/data/video/HDTF/10s"source_images_dir = "/home/nvidia/data/image/CelebA-HQ/300/0"output_dir = source_images_dirvideo_files_list = [os.path.join(source_videos_dir, f)for f in os.listdir(source_videos_dir)if os.path.isfile(os.path.join(source_videos_dir, f)) and f.endswith('.mp4') and not any(char.isalpha() for char in f.split('.')[0])]image_files_list = [os.path.join(source_images_dir, f)for f in os.listdir(source_images_dir)if os.path.isfile(os.path.join(source_images_dir, f)) and f.endswith('.jpg')]model_id = 'c'# Fill the task queuefor vid_file in video_files_list:for img_file in image_files_list:output_video = f"{os.path.splitext(os.path.basename(vid_file))[0]}_{os.path.splitext(os.path.basename(img_file))[0]}_{model_id}.mp4"output_video_path = os.path.join(output_dir, output_video)# Check if the output file already existsif not os.path.exists(output_video_path):device_id = calculate_device_id(vid_file, img_file)cmd = ["python", "multi_face_single_source.py","--retina_path", "retinaface/RetinaFace-Res50.h5","--arcface_path", "arcface_model/ArcFace-Res50.h5","--facedancer_path", "model_zoo/FaceDancer_config_c_HQ.h5","--vid_path", vid_file,"--swap_source", img_file,"--output", output_video_path,"--compare", "False","--sample_rate", "1","--length", "1","--align_source", "True","--device_id", str(device_id)]task_queue.put(cmd)# Create worker processes for each GPUworkers = []for gpu_id in range(len(gpu_locks)):  # Assuming you have 2 GPUsp = Process(target=worker, args=(gpu_id, gpu_locks[gpu_id]))p.start()workers.append(p)# Wait for all tasks to be processedtask_queue.join()# Signal workers to exit by adding None to the queue# Ensure enough exit signals for all workersfor _ in workers:task_queue.put(None)# Wait for all workers to finishfor p in workers:p.join()if __name__ == '__main__':main()"""在这个版本中,我引入了一个calculate_device_id函数,它基于视频文件和图像文件的路径计算出一个哈希值,然后取模得到设备ID。这样可以确保任务更均匀地分配到不同的GPU上,而不仅仅依赖于列表的索引。同时,我添加了设置CUDA_VISIBLE_DEVICES的代码到worker函数中,虽然这不是严格必需的,但它强调了每个工作进程将只看到并使用分配给它的GPU。这有助于避免潜在的GPU资源冲突问题。"""

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

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

相关文章

厚积薄发,详解 IoTeX 2.0 如何推动 DePIN 赛道迈向新台阶

背 景 DePIN 是加密货币行业的一个新兴垂直领域,也是本轮牛市最重要的叙事之一。DePIN 通常通过发行和分配代币来激励参与者,用户可以通过提供资源、维护网络、参与治理等方式获得代币奖励并产生直接的经济收益,从而重新洗牌财富分配方…

【Linux】网络通信基础:应用层协议、HTTP、序列化与会话管理

文章目录 前言1. 应用层自定义协议与序列化1.1 什么是应用层?1.2 再谈 "协议"1.3 序列化 和 反序列化 2. HTTP 协议3. 认识 URL(统一资源定位符)4. urlencode和urldecode5. HTTP 协议请求与响应格式5.1 HTTP 请求5.2 HTTP 响应 6. HTTP 的方法6.1 GET 方法…

50.TFT_LCD液晶屏驱动设计与验证(3)

(1)数据生成模块Verilog代码: module data_gen(input [9:0] hang ,input [9:0] lie ,input clk_33M ,input reset_n ,output reg [23:0] data ); //定义最大行、列parameter …

Git(分布式版本控制系统)(fourteen day)

一、分布式版本控制系统 1、Git概述 Git是一种分布式版本控制系统,用于跟踪和管理代码的变更,它由Linux、torvalds创建的,最初被设计用于Linux内核的开发。Git允许开发人员跟踪和管理代码的版本,并且可以在不同的开发人员之间进行…

mybatis-plus项目中使用mybatis插件

1. 确保项目添加MyBatis-Plus依赖以及适合的SpringBoot版本。 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>版本号</version> </dependency> 2. 创建mybatis自…

监控Windows文件夹下面的文件(C#和C++实现)

最近在做虚拟打印机时&#xff0c;需要实时监控打印文件的到达&#xff0c;并移动文件到另外的位置。一开始我使用了线程&#xff0c;在线程里去检测新文件的到达。实际上Windows提供了一个文件监控接口函数ReadDIrectoryChangesW。这个函数可以对所有文件操作进行监控。 ReadD…

SAP中生产版本维护

流程概述 本流程为生产版本主数据维护流程,当PBOM、工艺路线主数据维护完成后,方能进行此流程。由于S/4HANA系统中,生产版本被定义为BOM展开的必要条件,因此所有工厂都必须在运行物料需求计划与生产执行等流程前将生产版本维护完成,与此同时,生产版本数据还是财务模块发…

【C语言】数组栈的实现

栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#…

学习大数据DAY24 Shell脚本的书写

目录 shell 的变量 系统变量 特殊变量 运算符 if 选择结构 ---then 独立一行 case 语句 等值判断 上机练习 10 附加题 for 循环 while 循环 乘法表(双层嵌套) 上机练习 11 把附加题代码修改为循环形式 shell 的变量 系统变量 $HOME : 当前登录用户的 " 家…

套接字选项、广播和组播

1. 套接字选项(socket options) 每一个套接字(socket)在不同的协议层次(级别)上面有不同的行为属性(选项) 我们可以设置 / 获取指定的套接字选项 getsockopt&#xff1a;获取套接字的选项 setsockopt&#xff1a;设置套接字的选项 NAMEgetsockopt, setsockopt - get and set op…

python自动化运维 通过paramiko库和time库实现服务器自动化管理

目录 一.前言 二. 代码实现以及解析 2.1导入必要的库 2.2定义服务器信息 2.3创建 SSH 客户端连接函数 2.4执行远程命令函数 2.5获取系统信息函数 2.6重启服务函数 2.7 主函数 三.致谢 一.前言 在数字化时代&#xff0c;IT 基础设施的规模和复杂性不断增长&am…

Hadoop集群安装配置

文章目录 Hadoop部署配置集群配置历史服务器配置日志的聚集分发Hadoop群起集群Hadoop群起脚本 准备工作&#xff1a;需要3台虚拟机&#xff0c;每台虚拟机搭建好JDK并配置环境变量 Hadoop部署 1&#xff09;集群部署规划 注意&#xff1a;NameNode和SecondaryNameNode不要安…

批处理操作系统、分时操作系统、实时操作系统

批处理操作系统&#xff1a; 特点&#xff1a;批处理操作系统主要用于处理一系列作业。作业是把程序、数据连同作业说明书组织起来的任务单位&#xff0c;这些作业被组织成批作业。系统将这些作业按顺序执行&#xff0c;用户在提交作业后通常不需要等待作业完成&#xff0c;而是…

Hadoop NameNode 进入 Safe Mode 的问题分析与解决方案

随着大数据技术的不断发展&#xff0c;Hadoop 已经成为了处理海量数据不可或缺的一部分。然而&#xff0c;在使用 Hadoop 的过程中&#xff0c;我们经常会遇到 NameNode 进入 Safe Mode 的情况&#xff0c;这可能会导致集群暂时无法进行数据写入操作。本文将详细介绍 NameNode …

Java OpenCV 图像处理40 图形图像 图片裁切ROI

Java OpenCV 图像处理40 图形图像 图片裁切 在 OpenCV 中&#xff0c;Rect 类是用来表示矩形的数据结构&#xff0c;通常用于定义图像处理中的感兴趣区域&#xff08;Region of Interest&#xff0c;ROI&#xff09;&#xff0c;或者指定图像中的某个区域的位置和大小。Rect 类…

使用Apache SeaTunnel进行二次开发的实践分享

大家好&#xff0c;我是范佳&#xff0c;是Apache SeaTunnel社区的PMC member。今天给大家分享一些基于Apache SeaTunnel二次开发的内容。 这部分内容主要涉及代码层面的知识&#xff0c;如果大家有什么疑问&#xff0c;欢迎来社区找我交流&#xff01; 引言 大部分数据开发工…

如何使用 API list 极狐GitLab 容器镜像仓库中的 tag?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

【Pytorch实战教程】内存泄漏以及Pytorch中内存泄露的注意事项

文章目录 内存泄漏的原因内存泄漏的影响在不同编程语言中的内存泄漏在PyTorch中的内存泄漏示例总结内存泄漏是指在计算机 程序运行过程中, 动态分配的 内存由于某些原因 没有被释放或回收,导致这些内存块 无法再被使用或重新分配。 内存泄漏会导致程序占用越来越多的内存…

【微信小程序实战教程】之微信小程序 WXML 语法详解

WXML语法基础 从本章开始&#xff0c;我们就正式进入到了小程序项目开发学习的初级阶段&#xff0c;本章将介绍小程序的界面构成。有过网页开发学习经历的同学都知道&#xff0c;网页开发所使用的技术是HTML、CSS和JS&#xff0c;其中HTML用于描述整个网页的结构&#xff0c;也…

第三十一天 chrome调试工具

打开调试工具 页面空白处右击 检查 或者F12 使用调试工具 ctrl滚轮改变代码大小 左边是html 右边是css css可以直接改动数值左右箭头或者直接输入 查看颜色 ctrl0 复原浏览器大小 点击元素右侧出现样式引入 没有的话 说明类名或者样式引用错误 这里的.new-left是存在的 如果类…