首页
常用链接
关于
Search
1
Pytorch DDP
2,093 阅读
2
Pytorch 常见问题
1,210 阅读
3
视频时序切分
854 阅读
4
Semi-Supervised + Noisy Label
747 阅读
5
中文场景下的CLIP图文预训练
738 阅读
阅读
论文阅读
多模态理解
计算机视觉
Video Understanding
Segmentation
AIGC
机器学习
编程开发
C++
Python
LeetCode
Shell
Pytorch
模型加速
广告
广告基础知识
推荐算法
创意优选
购房/投资
职场经验复盘
默认分类
Search
标签搜索
python
Pandas
transformer
视觉传统方法
创意质量
git
shell
视频理解
Pytroch
nlp
DDP
图像自监督预训练
安装包
视频流行度
Jefxiong
累计撰写
50
篇文章
累计收到
7
条评论
首页
栏目
阅读
论文阅读
多模态理解
计算机视觉
Video Understanding
Segmentation
AIGC
机器学习
编程开发
C++
Python
LeetCode
Shell
Pytorch
模型加速
广告
广告基础知识
推荐算法
创意优选
购房/投资
职场经验复盘
默认分类
页面
常用链接
关于
搜索到
19
篇与
编程开发
的结果
2022-02-19
Pytorch DDP
1. Pytorch DDP 使用大致流程 使用 torch.distributed.init_process_group 初始化进程组 使用 torch.nn.parallel.DistributedDataParallel 创建 分布式模型 使用 torch.utils.data.distributed.DistributedSampler 创建 DataLoader 2. Pytorch DDP 训练报错信息 [W reducer.cpp:346] Warning: Grad strides do not match bucket view strides. This may indicate grad was not created according to the gradient layout contract, or that the param's strides changed since DDP was constructed. This is not an error, but may impair performance. Expected to mark a variable ready only once. RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. 3. DDP多卡训练需要主要事项? 为每个进程设置不同的随机种子 使用syncBN DistributedSampler 多进程的日志管理,文件创建管理,目录创建管理等 4. DDP 单机多卡卡住问题(hang/stuck/dead lock) 现象: GPU利用率100%,但是程序一直没有输出。 (1) 限制单进程并发数(无效) torch.set_num_threads(4) (2) 设置find_unused_parameters为True model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[int(args.local_rank)], output_device=int(args.local_rank), find_unused_parameters=True) # find_unused_parameters 的含义: 查找未用于计算损失的参数 (3) 排查NCCL问题? # 设置环境变量,看是否有更多的信息输出,更多环境变量参考 # https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html export NCCL_DEBUG=INFO export NCCL_DEBUG_SUBSYS=ALL (4) 在不同GPU上,部分分支的输出结果未参与损失计算 报错信息: RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. 由于过滤了样本,只有当样本满足一定条件下才计算损失(比如回归任务中,只有当pred与gt在一定范围内才计算损失),会导致不同GPU上,缺少梯度计算,导致导致程序假死 参考文献 Pytorch官方文档 Pytorch官方教程 Pytorch多gpu并行训练教程 DDP系列第一篇:入门教程 DDP系列第二篇:实现原理与源代码解析 DDP系列第三篇:实战与技巧 pytorch 多机多卡卡住问题汇总 PyTorch 源码解读之 DP & DDP:模型并行和分布式训练解析 https://discuss.pytorch.org/t/distributed-data-parallel-freezes-without-error-message/8009
2022年02月19日
2,093 阅读
1 评论
3 点赞
2021-05-23
Pytorch 常见问题
1.CUDA_VISIBLE_DEVICES设置无效,始终占用GPU0? 1. 在import torch前设置环境变量 2. CUDA_DEVICE_ORDER=PCI_BUS_ID CUDA_VISIBLE_DEVICES=3 python train.py 2.RuntimeError: CUDA error: device-side assert triggered 设置环境变量,让报错显示更具体的代码行 import os os.environ["CUDA_LAUNCH_BLOCKING"] = "1" 3.RuntimeError: DataLoader worker (pid xxx) is killed by signal: Aborted. what(): CUDA error: initialization error pytorch github issue ref google找到的文章,大多怀疑是内存问题 尝试修改pin_memory没有效用 尝试修改shm没有效果,mount -o remount,size=32g /dev/shm 尝试改小num_worker无效果(16->8)将num_workers设置为0可以解决问题,但肯定不是最优解!!! 4.resume training时,出现GPU OOM的问题 在DDP训练场景下进行resume training可能出现该问题,原因在于每个进程torch.load都加载在同一块卡上,导致最后OOM。解决方案: map_location指定加载在哪块卡上 checkpoint = torch.load(checkpoint_path, map_location='cuda:{}'.format(opts.local_rank)) 5.CUDNN和pytorch版本不匹配 可以从torch_stable.html下载安装 6 . unrecognized arguments: --local_rank,由于torch2.0升级导致,修复方案: python -m torch.distributed.launch xxx 替换为 torchrun xxx
2021年05月23日
1,210 阅读
0 评论
6 点赞
2021-05-11
Shell 常用命令总结
shell常用命令 查看CPU # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l # 查看每个物理CPU中core的个数(即核数) cat /proc/cpuinfo| grep "cpu cores"| uniq # 查看逻辑CPU的个数 cat /proc/cpuinfo| grep "processor"| wc -l 显示目录下文件,按文件大小排序 ls -Shlr #按文件大小(-S)从小到大(-r)排序显示(-hl) 查找文件中包含字符串 cat file.txt|grep -B 2 key # 查找包含key,并显示前两行 cat file.txt|grep -A 2 key # 查找包含key,并显示后两行 cat file.txt|grep -2 key # 查找包含key,并显示前后两行 查找包含字符串的文件: grep -rn "keyword" [files/dir] 查找符合条件的进程并kiil ps aux | grep "python test.py" | awk '{print $2}' | xargs kill -9 #适用于批量删除进程 查看硬盘占用情况 du -hs dir_name # h(human readable) s (而不列出子目录) df -h #列出文件系统的整体磁盘使用量 判断符合条件的文件是否存在 test -f 多线程下载数据 axel -n num_threads -q download_url rync+sshpass免密码同步数据 * rsync -av -e "sshpass -p [your_password] ssh -p [your_port]" src_path dst_path --exclude=exclude_pattern --include=include_pattern` rysnc 同步文件 rsync -avh --progress source_directory destination_directory 定时服务 `30 23 * * * find /data/home/jefxiong/PenguinID/videos/* -mtime +8 -exec rm {} \;` #每天23:00定时删除超过8天的数据 shm 不足 mount -o remount,size=32g /dev/shm mount 解决git无法加入软连接问题 mount --bind src dst 按规则删除指定文件命令 find . -name '*.DS_Store' -type f -delete #删除Mac下.DS文件 find . -name "*" -type f -size 0c | xargs -n 1 rm -f #删除空文件 find . -size 1k -exec rm {} \; #删除小于1k数据 按规则移动文件命令 find . -iname *.npy -exec mv {} dst_dir \; #移动numpy文件到指定目录下 多个python版本共用时,在脚本中指定python PYTHON=${PYTHON:-python} #PYTHON默认值为python,可以在命令行前设置为其他覆盖 #e.g. PYTHON=python3 (bash scripts/xxx.sh, 脚本中用$PYTHON替代 python awk awk '{print $1}' input.txt > out.txt #取input.txt 文件第一列保存到output.txt中 awk '{print $1,$2}' input.txt > out.txt #取input.txt 文件第一列和第二列保存到output.txt中 cat input.txt|awk '{sum+=$1} END {print "Average = ", sum/NR}' #求平均值 cat input.txt|awk '{sum+=$1} END {print "Sum = ", sum}' #求和 awk -F '[|]' '{print $1}' file.txt # 对fil.txt文件利用|进行分割,并取第1个元素输出 # awk 处理字符串: https://www.jianshu.com/p/8cb01a334527 批量加后缀、前缀重命名 for file in ./* ; do mv "$file" "$(basename "$file").mp4"; done; #批量加后缀名.mp4 删除特殊字符文件 # 1. 文件名为 a&b.c, 通过转义\和""解决 rm a\&b.c rm "a&b.c" # 2. 文件名为 -ab.c,通过加入参数-- rm -- -ab.c shell 编程 for i in ${list[@]}; do ... ; done for i in ${list[*]}; do ... ; done for i in exp1 exp2; do ... ; done for i in $(seq 1 100); do ...;done for((i=1; i<100; i++)); do ... ; done # c-like list=(12 34 56) echo ${#list[@]} # 获取数组大小 echo $# #获取执行命令参数个数
2021年05月11日
173 阅读
0 评论
0 点赞
2021-04-25
Python 工具库使用
用 magic vs filetype 实现视频类型判断 magic 比filetype更好用,能判断更多的类型,能够直接从文件buffer中判断 import magic # pip install python-magic import filetype # pip install filetype src_file = "x.some" print(filetype.guess(src_file)) print(magic.from_file(src_file, mime=True)) print(magic.from_buffer(open(src_file, 'rb'), mime=True)) jupyterlab IDE 函数定义跳转工具 jupyterlab-lsp parallel_apply[依赖pandarallel库] 对于多CPU机器,加速DataFrame的apply方法 安装python包,不更新其他依赖[--no-dependencies] pip3 install torch-fidelity --no-dependencies
2021年04月25日
150 阅读
0 评论
0 点赞
2021-03-29
数据结构/算法学习之LeetCode
数据结构 链表/树 典型链表/树问题 大数相加 反转链表 前序,中序,后序: 递归和迭代的遍历方式 平衡二叉树 二叉搜索树 树/链表参考文章 花花酱-树/链表 字符串 典型字符串问题 KMP Edit Distance 堆栈 典型堆栈问题 前缀表达式 利用栈的迭代解法 队列 典型队列问题 BFS 优先队列(heap) 图 典型图问题 DFS/BFS 最短路径 最小生成树(Kruskal, Prim两种算法) 图参考文章 花花酱-图 算法 查找 二分查找、哈希查找、常用set/map 排序 O(n^2)与O(nlogn)的排序算法,特点、冒泡/选择/插入,归并/快排/堆排序 回溯法 排列、组合 BFS/DFS 动态规划/贪心算法 从递归到动态规划 暴力解,复杂度: 指数级别时间复杂度 定义状态函数, 写状态转移方程(最优子结构)--递归实现: 指数级别时间复杂度 记忆化搜索: 递归实现 + 记忆化搜索 (自顶而下的方法): 多项式级别时间复杂度 自底而上求解--动态规划: 多项式级别时间复杂度 优化空间复杂度(例如对索引%2,只保留两行数据) 典型动态规划问题 斐波那序列 爬台阶 0-1背包问题/(无限使用背包问题,多维约束,物品依赖与排斥) 最长上升子序列: 动态规划时间复杂度$O(n^2)$ 最长公共子序列 单源最短路径算法 动态规划参考文章 花花酱-贪心/动态规划 参考链接 花花酱B站视频 拉钩+leetcode培训视频 geeksforgeeks 数据结构 Leetcode All in One 编程之法:面试和算法心得
2021年03月29日
104 阅读
0 评论
0 点赞
2021-03-24
流畅的Python笔记
以代码和注释方式,记录《流畅的Python》的笔记,持续更新 第一章 Python的数据类型 魔术方法(magic methods)是形式为"xxx()"的函数为Python的内置函数,用于实现一些特定的功能 用魔术方法实现可迭代对象 class MyList(): """ 通过实现'__getitem__()'和'__len__()' 完成 """ def __init__(self): self.data = range(0,100) def __getitem__(self, index): """ 实现该方法之后,对象变成可迭代和切片,e.g. print(MyList()[0]) for x in MyList(): print(x) """ return self.data[index] def __len__(self): """ 实现该方法之后,可以用len求对象的长度,e.g. len(MyList()) """ return len(self.data) 用魔术方法实现运算符重载 class Vector(): def __init__(self, x, y): self.x = x self.y = y def __repr__(self): """在print 对象的时候的输出格式, 如果没有__repr__方法定义,会输出对象在内存中的地址 """ return "{}(x = {}, y = {})".format(self.__class__.__name__, self.x, self.y) def __add__(self, vector): """ 重载加法+运算符 """ x = self.x + vector.x y = self.y + vector.y return Vector(x, y) def __mul__(self, scalar): """ 重载乘法*运算符 """ return Vector(self.x * scalar, self.y * scalar) print(Vector(1,2)) #Vector(x = 1, y = 2) print(Vector(1,2) + Vector(3,4)) #Vector(x = 4, y = 6) print(Vector(1,2)*0.5) #Vector(x = 0.5, y = 1.0) 第二章 序列构成的数组 两种生成序列的方法 # 利用生成器生成的序列(元组构建生成器)可以节约内存,不会在内存中创建所有需要的元素,当列表长度过长时,优先选择生成器方式 x_generator = (i for i in range(10000000)) # 生成器,type(x_generator)=<class 'generator'> x_list = [i for i in range(10000000)] # 列表, type(x_list)=<class 'list'> 利用list[::-1]实现反转的原理 列表切片的常规用法,list[start:end:stride], list[::-1]省略了前两个,-1表示取值的步长,因此可以实现列表反转的功能 利用count实现列表/元组计数 l = [1, 1, 2, 3] t = (1, 1, 2, 3) print({x:l.count(x) for x in set(l)}) print({x:t.count(x) for x in set(t)}) 对比 list、tuple、queue、deque(collections) # TODO 第三章 字典和集合 几种不同的dict from collections import defaultdict from collections import OrderDict # {} 内置字典 # OrderDict 是有序字典 # defaultdict #当key不在字段内,默认构建初始值 dict/set vs list 内部维护了散列表,以空间换时间。代码中涉及在大数组中查找key时,可以考虑为dict实现。
2021年03月24日
226 阅读
0 评论
2 点赞
2020-07-12
ab(Apache HTTP server benchmarking) 服务压测
工具安装 yum install httpd-tools apt-get install apache2-utils 参考链接 官方命令说明 压力测试常用指标与测试工具ab
2020年07月12日
79 阅读
0 评论
0 点赞
2020-02-11
此内容被密码保护
加密文章,请前往内页查看详情
2020年02月11日
11 阅读
0 评论
1 点赞
2019-10-01
Git常用命令总结
Git常用操作 git status # 确认下变更文件:新增、删除、更新? git diff # 确认下修改内容 git log # 查看commit记录 git add your_update_file #修改或者增加文件后,添加到git存储 git commit -m "做了什么修改" git push origin master:master #提交本地的master分支到远程仓库的git分支 git reflog #查看所有commit记录,包括被丢弃的commit,可以用于版本redo的用途 git commit --amend #追加文件到上次提交 git checkout --orphan new_branch # 新建独立的branch git branch -d branch_to_be_delete # 删除本地仓库branch git push <remote> --delete <branch> # 删除远程仓库branch git branch -m dev # 将当前分支重命名为dev 如何清除部分commit记录 git rebase -i start_commit_id end_commit_id # 合并commit记录 git rebase --abort #取消rebase 取消在git中track文件 git rm -r --cached file/folder # 删除记录,但不删除本地文件 git rm -r file/folder # 删除记录,并删除本地文件 git LFS 大文件管理(上传模型数据相关文件) lfs文件上传问题参考git lfs track *.pb #添加模型文件*.pb到LFS中 git lfs migrate import --include="*.so,*.pb" git lfs ls-files #查看添加到LFS的文件 git lfs push --all origin # 解决lfs文件上传问题 处理git pull时,文件冲突问题 git stash save git pull git stash pop git问题解决参考文章 Code Review/合作开发 Code Review introduction 参考链接 详解 Git 大文件存储(Git LFS) git - 简易指南 廖雪峰Git教程
2019年10月01日
161 阅读
0 评论
0 点赞
2019-09-17
Blob in Caffe
Class Blob A wrapper around SyncedMemory holders serving as the basic computational unit through which Layer, Net, and Solver interact. Caffe 由Blob、Layer、Net、Solver四大部分组成,其中Blob是之中最底层的结构。caffe的理念就是自下而上不断封装,使得上层代码不需要理会下层的具体操作,使代码变得清晰简洁。为了能够理解其它几层,我们需要从Blob开始。 首先,我们看看Blob类的声明,下面是Blob的成员变量 protected: shared_ptr<SyncedMemory> data_; shared_ptr<SyncedMemory> diff_; shared_ptr<SyncedMemory> shape_data_; vector<int> shape_; int count_; int capacity_;
2019年09月17日
153 阅读
0 评论
0 点赞
2019-03-24
Python标准库threading
threading 用来管理一个进程中的并行操作(线程) 在python中简单使用线程 import threading def worker(): print('Worker') threads = [] for i in range(5): t = threading.Thread(target = worker) threads.append(t) t.start() target参数是线程调用的函数,threading.Thread还可以通过name指定线程名称,args指定调用函数传入的参数。 start()函数,开始执行线程。另外,theading 中daemon(设置线程是否为后台线程)、join(后台线程阻塞)也是常用的用法。此处就不一一举例了。 线程同步 多线程的程序面临一个重要的问题,由于线程之间的资源是共享的,当不同线程访问共享资源时可能出现访问冲突(例如消费者和生产者的执行)。另外,当线程之间可能需要等待某个事件发生后,才被激活而执行(例如行人、车辆必须等待绿灯才能通过) theading中有lock、Rlock、condtion、Semaphore、Event实现线程的同步,当然各个方法还是有不同的特点。 首先,我们通过一个简单的栗子来感受下,多线程不进行同步可能出现的问题。 import threading import time count =0 def addcount(): global count for i in range(1000): count += 1 for i in range(10): t = threading.Thread(target=addcount) t.start() time.sleep(3) print count 理论上上述代码的结果应该是1000*10,但是当我们运行程序发现每次的结果都不同,并且结果都小于10000。对全局变量的修改可以分为取值和赋值两个阶段,假设某一时刻count=100,如果按照方式①Thread1取值(temp1=100)-->Thread1赋值(count=temp1+1)-->Thread2取值(temp2=101)-->Thread2赋值(count=temp2+1)这种方式,运行结果count为102。但是如果线程的顺序变为方式②Thread1取值(temp1=100)-->Thread2取值(temp2=100)-->Thread1赋值(count=temp1+1)-->Thread2赋值(count=temp2+1),运行结果count为101。 如果想要使得程序严格按照方式①的顺序运行,我们就需要进行线程的同步。 lock lock(锁)的工作原理: 所有的线程只有一把锁,谁抢到就执行哪个线程,当拥有锁的线程结束操作,需要释放锁让别的线程去竞争。 我们可以对上述的代码进行改写 import threading import time count =0 lock = threading.Lock() def addcount(): global count for i in range(1000): lock.acquire() count += 1 lock.release() for i in range(10): t = threading.Thread(target=addcount) t.start() time.sleep(3) print count 与原来的代码不同之处仅仅在于获取锁acquire()、释放锁release()的两个操作而已,Lock.acquire(blocking=True, timeout=-1),blocking参数表示是否阻塞当前线程等待,timeout表示阻塞时的等待时间 threading 中还有RLock与Lock功能类似,但是在同一个线程内可以多次调用RLCOK.acquire来获取锁,Lock如果多次accuire则会出现死锁的情况。 这样的RLock对比与Lock在哪些问题上有优势呢?(TO DO) GIL(Global Interpreter Lock) GIL 全局解释锁(TO DO) condtion condition 提供了比Lock更复杂的功能。线程只有满足一定条件后才能去竞争锁,不满足条件的线程处于等待池(当前线程调用condtion.wait()进入等待),直到收到通知(其它线程调用condition.notify())才退出等待状态,再开始去竞争锁。 下面以消费者和生产者为例(始终保证生产足够,但不过剩(产品数量限制在30以内):) ) import threading import time condition = threading.Condition() class Producer(threading.Thread): def run(self): while(1): global x print 'producer accquire lock' condition.acquire() print 'producer get lock' if x > 30: print 'x>need_max producer wait,and release lock' condition.wait() else: x = x + 5 print 'producing',x condition.notify() print 'producer done, notify others' condition.release() #print 'producer release lock' time.sleep(1) #暂停线程,避免与consumer争lock class Consumer(threading.Thread): def run(self): while(1): global x print 'consumer accquire lock' condition.acquire() print 'Consumer get lock' if x == 0: print 'x==0 consumer wait,and release lock' condition.wait() else: x = x - 1 print 'consuming ',x time.sleep(1) condition.notify() print 'consumer done, notify others' condition.release() #print 'consumer release lock' time.sleep(1) x = 5 p = Producer() c = Consumer() p.start() c.start() 上述代码首先从Thread中继承得到两个子类。线程Thread类的继承只需要实现run方法即可。run方法在线程执行start启动线程被调用。Producer与Consumer的结构基本相同,只是判断进入wait或notify的条件不一样而已。当生产者当生产的量大于一定的阈值,调用wait进入等待状态,此时Consumer获得lock,消耗一个产品,并通知生产者继续生产。执行的结果如下所示,产品x的数量始终保持在30左右。 Consumer get lock consuming 22 consumer done, notify others producer get lock producing 27 producer done, notify others producer accquire lockconsumer accquire lock producer get lock producing 32 producer done, notify others Consumer get lock consuming 31 consumer done, notify others producer accquire lock producer get lock x>need_max producer wait,and release lock consumer accquire lock Consumer get lock consuming 30 consumer done, notify others consumer accquire lockproducer accquire lock Semaphore (TO DO) Event 事件对象是实现线程之间安全通通信的一种简单的方法。Event内部管理着一个内部标志,调用者可以用set()和clear()方法控制这个标志。其他线程可以使用wait()暂停直到设置这个标志,即线程调用wait()等待,调用的线程被阻塞,直到event被set或timeout,才继续执行。 以车辆等待红绿灯为例。 import threading import time class VehicleThread(threading.Thread): def __init__(self,threadName,event): threading.Thread.__init__(self,name=threadName) self.event = event def run(self): time.sleep(int(self.getName()[7:])) print self.getName(),'arrive,wait for green light' self.event.wait() print self.getName(),'passed' green_light_event = threading.Event() vehicleThreads = [] for i in xrange(10): vehicleThreads.append(VehicleThread('vehicle'+str(i),green_light_event)) for t in vehicleThreads: t.start() while threading.activeCount() > 2: #在python中除了主线程还有一个Thread-1, #IPython运行有5个线程?(Thread-5 Thread-1 MainThread Thread-4 IPythonHistorySavingThread) green_light_event.clear() time.sleep(3) print "green light appera!!! let's GO" green_light_event.set() time.sleep(1) # for t in threading.enumerate(): # print t.getName() thread与Queue的联合使用 (TO DO) 参考链接 Python Standard Library Python Standard Library-threading Python Moudle of the Week--threading Python 标准库学习 GIL Queue and Thread
2019年03月24日
169 阅读
0 评论
0 点赞
2019-03-24
python 迭代器&生成器
__iter__为python中的内建函数,如果想要定义的对象是iterable,你就需要定义__iter__ next(__next__)常与__iter__共同使用,构成迭代器(iterator) 带有yield关键字的函数为生成器(generator) 为了理解这几个关键字和迭代器、生成器。我们从一个常用的斐波那契数列(Fibinacci)开始 常规实现Fibinacci序列生成 def fib(max): n,a,b = 0,0,1 fib_list = [] while n < max : fib_list.append(b) a,b = b, a+b n = n +1 return fib_list
2019年03月24日
147 阅读
0 评论
0 点赞
1
2
粤ICP备2021042327号