作者: remaper
Mix Precision Training 混合精度训练
- Binaryconnect: Training deep neural networks withbinary weights during propagations @2015
- Binarized neural networks. InAdvances in Neural Information Processing Systems @2016
1. 背景
Year
|
Name
|
Param
|
From
|
2018
|
110M
|
OpenAI
|
|
2018
|
349M
|
Google
|
|
2020
|
175B
|
OpenAI
|
|
2022
|
540B
|
Google
|
2. 实现
- 大幅减少内存消耗:50%?
- 运算加速,FP16肯定要比FP32要快
vm template 原理浅析
1. 背景
2. vm template 原理
RunD – A Lightweight Secure Container Runtime
1. 设计目标
2. 问题分析
2.1 并发启动的开销
2.2 高密部署的瓶颈
nr_dying_descendants 引发的在线业务性能抖动
最近发现一则比较奇怪的业务性能抖动问题
简单来说,就是离线作业频繁的触发oom,导致在线业务指标陡增。理论上来说,离线作业触发自身硬限,不应该导致其他容器出问题才是
先来说一下我们的 memory cgroup 层级结构,可以简单理解为如下:
/cgroups/v2/kubepods/
/cgroups/v2/kubepods/online/a -> a为在线服务
/cgroups/v2/kubepods/offline/job1 -> job1 为离线服务
通常来说,为了解决混部的内存争抢问题,我们会对整个 offline 大框设置一个内存上限,防止离线作业使用内存太多,导致在线服务出现内存压力。这看起来似乎没什么问题。
不过最近一个问题,发现离线 job1 频繁 oom,引发了在线的性能抖动
最后定位的结论如下:
- /cgroups/v2/kubepods/offline/cgroup.stat 下看到有大量的 nr_dying_descendants
- offline 大框频繁出发 oom
- oom 的回收过程有个效率不太好的地方,导致 oom 回收效率底下 -> 导致内核各种锁争抢严重 -> 进程sys高 -> cpu排队严重 -> 在线业务性能抖动
根因分析:nr_dying_descendants 的原因是由于容器被销毁时,容器内还有未完全回收干净的 page cache,所以内核不会立即释放这个 cgroup(用户态操作系统从 /cgroups 文件系统下已经看不到了,但是内核态的数据结构还在)
cat /cgroups/v2/kubepods/online/cgroup.stat
nr_descendants 10
nr_dying_descendants 4172
这就有一个问题,如果有大量的dying cgroups,内核在oom处理过程中:
- 如果是cgroup oom,会优先尝试从 dying cgroups 回收内存,但是最多只回收5个 -> 这个地方有效率问题
- 如果是整机回收,不处理dying cgroups内存
TMO – Transparent Memory Offloading in Datacenters
1. INTRODUCTION
- google的方案,g-swap
- facebook的方案,tmo
- 核心是压缩
- 非常简单
- 好处:不用解决异构这些复杂的问题(感觉解决了?做了负载分类)
- 坏处:不利于最大化的 memory-cost saving
- promotion rate 的设定依赖离线分析
- 所有应用的 promotion rate 是一样的。没有考虑不同业务对内存的敏感性,以及不同分层设备的 performance(后者其实有简单的考虑,具体的 P% 的设备就取决于 far memory 到 near memory 的性能表现)
- g-swap的观点:为了保证应用程序的性能,memory offloading 应该控制在一个预先配置好的比例下面
- tmo的观点:facebook 对它们部署规模最大的程序,发现,在一些高速设备上,提高 memory offloading 比例,可以提高性能。 –> 反人类假设??
- 核心是卸载(但是卸载的backend 支持 compressed memory pool,也支持 NVMe SSDs)
- 不需要离线分析,依赖 PSI 的反馈,直接单机决定不同的 offloading 比例。不依赖app的任何先验知识(g-swap的方案就有一个冷启动问题,新app默认不回收任何内存)
- PSI accounts for application’s sensitivity to memory-access slowdown(这里其实是比较误导的,facebook认为psi观测出来的内存延迟一定是对业务敏感的,但是实际上不同的业务对延迟的敏感性是不一样的,简单来说这个是充分不必要条件)
How to install cuda and pytorch dev environment on thinkpad w530 & ubuntu 20.04
最近发现在笔记本上用 cpu 来训练模型效率还是太慢了,正好我笔记本上有一块 nvidia gpu,准备折腾一下把这块 gpu 用起来
由于在笔记本环境下安装 gpu 开发环境比较痛苦,虽然最终失败了,但是过程比较有意义,值得备忘一下
我的开发环境主要是 pytorch + cuda
硬件环境就是 thinkpad w530 + 32g + K1000M
由于笔记本的 gpu 通常型号比较老,并不是大部分的 pytorch 都支持
1. 安装 cuda
网上有很多资料,怎么安装 nvidia-cuda-toolkit 的,apt install nvidia-cuda-toolkit 就可以直接装
但是我发现装完了之后没法用,pytorch 没法检测到 cuda 环境。这两个东西不完全是一个东西,有挺多差异的。
python3 -c ‘import torch; print(torch.cuda.is_available())’ 必须返回 true
最后用官方的安装方法成功了
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 wget https://developer.download.nvidia.com/compute/cuda/11.7.0/local_installers/cuda-repo-ubuntu2004-11-7-local_11.7.0-515.43.04-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu2004-11-7-local_11.7.0-515.43.04-1_amd64.deb sudo cp /var/cuda-repo-ubuntu2004-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/ sudo apt-get update sudo apt-get -y install cuda
2. 安装 nvidia-driver
ubuntu 默认源里面会有一些基本的 nvidia-driver
ubuntu-drivers devices 可以看到
# ubuntu-drivers devices == /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 == modalias : pci:v000010DEd00000FFCsv000017AAsd000021F5bc03sc00i00 vendor : NVIDIA Corporation model : GK107GLM [Quadro K1000M] manual_install: True driver : nvidia-driver-390 - distro non-free driver : nvidia-340 - distro non-free recommended driver : nvidia-driver-418-server - distro non-free driver : xserver-xorg-video-nouveau - distro free builtin
这里面会推荐你使用 nvidia-340
但是我的实际测试来看,nvidia-340是没法用的,安装完了之后显示器各种异常,最后安装到 nvidia-driver-390 解决了显示器异常的问题
但是nvidia-driver-390 版本太低,cuda 现在依赖的 nvidia-driver 版本都是470以上了,所以光有 nvidia-driver 是不行的,必须和 cuda 配套。
最终在安装 cuda 的时候会自动安装 nvidia-driver 配套驱动,其实不用自己搞
安装完,需要重启机器,重启后 nvidia-smi 检查能不能看到显卡信息
Stock Selection via Spatiotemporal Hypergraph Attention Network – A Learning to Rank Approach
论文原址:https://www.aaai.org/AAAI21Papers/AAAI-7907.SawhneyR.pdf
这几年研究把深度学习应用到量化交易和传统投资决策的论文并不少,但都有2个问题:
- They do not directly optimize the target of investment in terms of profit
- and treat each stock as independent from the others, ignoring the rich signals between related stocks’ temporal price movemen
为了解决这些问题,作者提出了一种叫 STHAN-SR 的超图神经网络。并通过对美3大交易所最近6年的数据,证明这个网络在当前所有股票预测算法里面是最优的
Introduction
美股市场,68万亿,19年
forecasting:预测
highly volatile and non-stationary nature – 股票市场具有很强的波动性
synergy 协同
当前主流的股票预测算法,最大的弊端就是不以投资收益为优化目标。因为这些算法,要么是基于回归来预测价格,要么基于分类来做交易决策,这种分类和回归的优化目标是为了提高股票价格走向的准确性或最小化预测股票收益的误差,而不一定是为了直接利润
(有什么不一样吗??一脸懵比)
第二个弊端就是不考虑股票之间的相关性,总是把这些股票作为独立的个体来分析,或者使用一个过于简化的股票市场模型,一个由单个股票之间的成对关系组成的图表,但在现实中,这与真正的市场是相反的
Software-defined far memory in warehouse-scale computers
论文重点
- 采用软件zswap的方式进行cold memory数据压缩
- google的业务有32%的memory数据是cold memory,其中20%的数据是可压缩的,压缩效率中位数为3倍,那么TCO有4.2%的收益
- 该压缩策略保证了SLA不受影响:通过cold memory和promotion rate的模型保证
- 压缩解压缩的开销不大,完全可以接受
- 使用ML进行autotuner
1 introduction
- 随着资源的scaling,一个资源瓶颈会影响整个scaling的TCO。
- DRAM成为scaling的瓶颈,memory的TCO减少逐渐放缓
- 随着大数据workload的普及,主流的in-memory computing的方式加速了DRAM的需求
- 不影响应用的性能
- 应用数量多且种类多样,不能对每个应用单独优化(不现实),需要对业务透明且robust的机制,有效使用Far memory
- 动态的cold数据行为:业务的数据冷热是会变化的,比如不同该时间段
Concurrency management in BPF
eBPF 对并发编程的支持是非常弱的
有一些讨论:
- https://lists.iovisor.org/g/iovisor-dev/topic/bpf_concurrency/74407447
- https://lwn.net/Articles/779120/
但是你甚至在 eBPF 的官方文档 https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md 里面几乎找不到任何关于并发的描述,除了 map.atomic_increment() 接口
但是这个借口也很奇怪。为了突出这个接口是原子的,线程安全的,难道其他接口就不是了吗?但好像又不是,因为 eBPF 里有大量的示例,并没有对 map 做特殊的并发控制,所以理论上可以认为,其他大部分 map 操作接口,也是线程安全的
线程安全验证
测试代码如下:
// calculate latency int trace_run(struct pt_regs *ctx, struct task_struct *prev) { u32 pid = bpf_get_current_pid_tgid(); u64 *tsp; if (pid <= 1) { return 0; } pid = 10000; u64 ts = bpf_ktime_get_ns(); start.update(&pid, &ts); #define __OP__ == tsp = start.lookup(&pid); if (tsp __OP__ 0) { dist.increment(bpf_log2l(1)); } tsp = start.lookup(&pid); if (tsp __OP__ 0) { dist.increment(bpf_log2l(1)); } /** 重复N次 **/ tsp = start.lookup(&pid); if (tsp __OP__ 0) { dist.increment(bpf_log2l(1)); } tsp = start.lookup(&pid); if (tsp __OP__ 0) { dist.increment(bpf_log2l(1)); } start.delete(&pid); return 0; }
这段代码,修改自 bbc 工具集自带的 runqlat.py
这段代码实际上是在构造一个冲突场景,来验证 trace_run 到底是并行执行还是串行执行的。代码的逻辑是在一个超高频触发的钩子(调度器进行上下文切换)函数里,先在 map 里插入一个固定key(pid)的元素,然后查询 N 次,每次查询如果 key 不存在,计数器就 +1,最后把 key 从 map 里面删除掉,如果:
- trance_run 是串行的,那么技术器永远都是 0,因为在一个串行执行的逻辑里,插入元素后,不管查询多少次,元素必然是存在的
- 如果 trace_run 是并行的,那么就存在一个条件,一定有一个 cpu,在另外一个 cpu 查询 key 是否存在的时候,执行到了函数结束的地方,把 key 从 map 里面删掉了
事实证明,trace_run 是并行执行的,并且中间 lookup 的次数越多,冲突的概率就越大