Hello World
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick StartCreate a new post1$ hexo new "My New Post"
More info: Writing
Run server1$ hexo server
More info: Server
Generate static files1$ hexo generate
More info: Generating
Deploy to remote sites1$ hexo deploy
More info: Deployment
TensorRT 模型构建与推理
TensorRT 模型构建与推理TensorRT 简介TensorRT 是由 NVIDIA 发布的深度学习框架,用于在其硬件上运行深度学习推理。TensorRT 提供量化感知训练和离线量化功能,用户可以选择 INT8 和 FP16 两种优化模式,将深度学习模型应用到不同任务的生产部署,如视频流、语音识别、推荐、欺诈检测、文本生成和自然语言处理。TensorRT 经过高度优化,可在 NVIDIA GPU 上运行, 并且可能是目前在 NVIDIA GPU 运行模型最快的推理引擎。关于 TensorRT 更具体的信息可以访问 TensorRT官网 了解。
安装 TensorRTWindows默认在一台有 NVIDIA 显卡的机器上,提前安装好 CUDA 和 CUDNN,登录 NVIDIA 官方网站下载和主机 CUDA 版本适配的 TensorRT 压缩包即可。
以 CUDA 版本是 10.2 为例,选择适配 CUDA 10.2 的 zip 包,下载完成后,有 conda 虚拟环境的用户可以优先切换到虚拟环境中,然后在 powershell 中执行类似如下的命令安装并测试:
123456cd ...
CPU/GPU联合编程
CPU/GPU联合编程由示例代码可以知道,只要调用了 cuda 函数把模型移动到 GPU 之上,我们就可以使用 CUDA global 核函数在GPU上进行并行运算。
12345678model = ToyModel().cuda(device_ids[0]) # 这里复制模型到 GPU 之上ddp_model = DDP(model, device_ids)loss_fn = nn.MSELoss()optimizer = optim.SGD(ddp_model.parameters(), lr=0.001)optimizer.zero_grad()outputs = ddp_model(torch.randn(20, 10))
但是我们忽略了一个问题,就是 PyTorch 怎么知道此时应该调用GPU对应的 global 核函数?为什么 PyTorch 就不调用 CPU 函数或者其他设备的函数了?这就是我们接下来需要分析的。
Dispatcher 机制在PyTorch中,operator 所表现出预期行为是由很多机制共同作用导致的,比如:
做实际工作的kernel。
是否支持反向 ...
CUDA编程模型基础
CUDA编程模型基础CUDA是英伟达为GPU编程提供的异构编程库。
异构模型CUDA编程模型是一个异构模型。程序运行在一个异构系统之上,这个异构系统由CPU和GPU构成,它们之间由总线分开,程序运行时候是由CPU和GPU协同工作。
在CUDA之中,有两个重要概念:host和device。
Host :CPU及其内存。
Device :GPU及其内存。
因此,CUDA 架构下的一个程序也对应分为两个部份:Host 代码和Device代码,它们分别在CPU和GPU上运行。host与device之间可以通信进行数据拷贝。
主机代码(Host Code):在 CPU 上执行的部份,使用Linux(GNU gcc)和Windows(Microsoft Visual C)编译器来编译。大致可以认为认为C语言工作对象是CPU和内存条。
设备代码(Device Code):在GPU上执行的部份,使用 NVIDIA NVCC 编译器来编译。大致可以认为 CUDA C工作对象是GPU及GPU上内存(也叫设备内存)。
123456789101112131415161718+------------- ...
Dispatcher
Dispatcher我们接下来通过源码来看看。
虚函数表
Schema 例子
每个kernel 算子(虚函数)都有一个对应的schema,我们可以从 aten/src/ATen/native/native_functions.yaml 之中找到一些虚函数 schema 的例子,这些都是以字符串的形式呈现。我们可以看到,schema 包括算子名称(比如zero_sparse_),输入参数个数和类型,返回值类型,是否需要check,如何分发等等。
123456789101112131415161718192021222324252627# zero 操作对应的虚函数表- func: zero_(Tensor(a!) self) -> Tensor(a!) device_check: NoCheck # TensorIterator variants: method, function dispatch: CPU, CUDA: zero_ Meta: zero_meta_ SparseCPU, SparseCUDA: zero_sparse_ ...
DistributedDataParallel 初始化方法&存储
DistributedDataParallel 初始化方法&存储回顾基本概念关于分布式通信,PyTorch 提供的几个概念是:进程组,后端,初始化,Store。
进程组 :DDP是真正的分布式训练,可以使用多台机器来组成一次并行运算的任务。为了能够让 DDP 的各个worker之间通信,PyTorch 设置了进程组这个概念。
后端 :后端这个概念是一个逻辑上的概念。本质上后端是一种IPC通信机制。
初始化 : 虽然有了后端和进程组的概念,但是如何让 worker 在建立进程组之前发现彼此? 这就需要一种初始化方法来告诉大家传递一个信息:如何联系到其它机器上的进程。
Store : 可以认为是分布式键值存储,利用这个存储就可以在组中的进程之间共享信息以及初始化分布式包 (通过显式创建存储来作为init_method的替代)。
初始化进程组在调用任何 DDP 其他方法之前,需要使用torch.distributed.init_process_group()进行初始化。该方法会初始化默认分布式进程组和分布式包。此方法会阻塞,直到所有进程都加 ...
DistributedDataParallel 总述&如何使用
DistributedDataParallel 总述&如何使用数据并行因为DistributedDataParallel 是数据并行,所以首先通过两个图,复习一下什么是数据并行。
我们可以看到,模型并行与数据并行的区别。
第二张图来自fairscale github源码,清晰的给出了一个数据并行的运行模式,具体包括:
模型分片,本地前向计算,本地反向传播,AllReduce来同步梯度,本地更新梯度这几步。
DDP 运行逻辑Torch.distributed 包 为多个计算节点的 PyTorch 提供多进程并行通信原语,可以并行化跨进程和跨集群的计算。torch.nn.parallel.DistributedDataParallel基于torch.distributed 包的功能提供了一个同步分布式训练wrapper,这个wrapper可以对 PyTorch 模型封装进行训练。其核心功能是基于多进程级别的通信,与Multiprocessing package - torch.multiprocessing 和 DataParrallel 提供的并行性有明显区别。
以 ...
PyTorch分布式训练
PyTorch分布式训练数据并行训练PyTorch 为数据并行训练提供了多种选项。一般来说,应用会从简单到复杂,从原型到量产。这些应用共同的发展轨迹是:
如果数据和模型可以放在一个 GPU 中,并且不关心训练速度,就使用单设备(single-device)训练。
如果服务器上有多个 GPU,并且您希望以最少的代码更改来加速训练,那么可以使用单机多 GPU DataParallel。
如果您想进一步加快训练速度并愿意编写更多代码来设置它,可以使用单机多 GPU DistributedDataParallel。
如果应用程序需要跨机器边界进行扩展,请使用多机 DistributedDataParallel 和 启动脚本。
如果预期会出现错误(例如,OOM)或者资源可以在训练期间动态加入和离开,则使用torchelastic启动分布式训练。
Torch如何使用GPU
_apply 方法
遍历 _parameters:
对参数调用fn进行处理,得到param_applied。
用 param_applied 重新设置参数。
如果参数有梯度,则:
对参数的grad调用fn进 ...
SLAM数学基础
SLAM数学基础三维空间的刚体运动刚体:刚体是指在运动中和受力作用后,形状和大小不变,而且内部各点的相对位置不变的物体。
旋转矩阵$$ SO(n)={R \in \mathbb{R}^{n \times n}|R R^T = I, det(R)=1} $$
$SO(n)$是特殊正交群,刚体在两个坐标系之间的变换可以公式化表述为
$$ a’=Ra+t $$
$t$表示的是从a坐标系原点到b坐标系原点的向量
三维旋转矩阵的计算如下
$$\begin{bmatrix} e^T_1 e’_1 & e^T_1 e’_2 & e^T_1 e’_3\ e^T_2 e’_1 & e^T_2 e’_2 & e^T_2 e’_3 \ e^T_3 e’_1 & e^T_3 e’_2 & e^T_3 e’_3\\end{bmatrix}$$
$e_i$是某一坐标系的基向量
齐次坐标连续变换坐标系时,使用上述的变换公式不是线性的表述,写起来会很麻烦,如
$$c=R_2(R_1a+t_1)+t_2$$
因而在三维向量的末尾加上一个1,就变为了四维向 ...
权重初始化
模型优化kaiming初始化的推导
权重初始化为什么需要权重初始化网络训练的过程中,容易出现梯度消失(梯度特别的接近0)和梯度爆炸(梯度特别的大)的情况,导致大部分反向传播得到的梯度不起作用或者起反作用。研究人员希望能够有一种好的权重初始化方法:让网络前向传播或者反向传播的时候,卷积的输出和前传的梯度比较稳定。合理的方差既保证了数值一定的不同,又保证了数值一定的稳定。(通过卷积权重的合理初始化, 让计算过程中的数值分布稳定)
推导的先验知识
参照上面的卷积图,对输入的特征图进行的卷积。具体要研究的是输出的一个点的方差(紫色点)。所以是通过黄色的输入(个)和绿色的卷积参数(个)去计算一个输出值(紫色输出)的方差。 一个点对应于原论文里面的说法为a response。感觉这个是理解权重初始化的重点。基于独立同分布的强假设:输入的每个值都是独立同分布的,所以和独立同分布的参数进行卷积得到结果的分布也是相同的。所以其他的3个输出点的方差也是一样的。进一步说,虽然输入是个不同的值。但是我们可以这样认为:有一个满足某分布的随机变量,然后随机抽样48次,这48个值就可以组成了输入,且独立同 ...