- (Possibly) interesting technical toys (see the Github profile at the first link below)
- Academic works and notes (see his CV as a PhD at the second link below)
- Everyday life of a trivial human being
HypeReca: 面向推荐模型训练的分布式嵌入向量数据库
闲话 - 前 这是一篇 ATC'25 论文 的中文简要版本. 然而这篇文章在学术创新上实在乏善可陈,正好多说一点闲话了。这也是为什么没有在文章发表前就把博客写出来,不然万一被撤稿了可就搞笑了。 写这篇博客是 laekov 一直以来坚持要把自己发表的每篇文章都翻译成中文,因为曾经的 laekov 觉得凭什么论文都要用英文写呀,而且八股文读起来好麻烦呀,用中文简洁明了地把文章讲清楚不是更好吗。 然后天真的 laekov 读博五年一共也就中了两篇文章。这是第二篇,中稿时间是毕业前三个月。 HypeReca 这个名字是 Hybridly Partitioned Embeddings for Recommendation Model Training Acceleration 的各种胡乱拼凑里找了个听起来好听一点的。 背景 基于深度学习的推荐模型是现在主流的推荐算法,它分为学习元素特征的稀疏部分和学习元素间关系的稠密部分。 稀疏部分主要是非常稀疏的嵌入表 embedding tables,它们可能会有 TB 级别甚至更大,所以得要很好地分布式地存下来,并且支持高吞吐地读取和更新。 稠密部分通常由传统的 DNN 构成,属于计算密集型任务(比如 CNN / MLP),所以得用 GPU 来加速。 在做分布式训练的时候,这两部分由于特性不同所以采用了不同的并行方式:稀疏部分用模型并行(切分存储),稠密部分用数据并行(小模型,大 batch size)。 这两部分之间通过 all-to-all 集合通信来传输所需的数据和用于更新的梯度。 然后就会发现在 scale up 的时候两部分之间的通信是瓶颈,可能会占到迭代时间的 90% 以上。 解决方案 这篇文章的核心想法其实很直白:embedding data 有冷有热。 把频繁访问的热数据找出来,也用数据并行的方法来存,重复地放到所有 GPU 上。 接下来要解决两个问题: 首先,挑多少热数据比较合适? 热数据越多,可以省掉的 all-to-all 通信就越多,但同步热数据所需的 all-reduce 量就越大。 这里正好是一个在单峰函数上找最优的 trade-off。结合实际数据建模观察一下即可。...
20250818那个夏天的十年之后
在最近第二次突然意识到,那场 noi 已经过去十年了 laekov 曾经是一个 oier,也不止是一个 oier laekov 曾经是一个上进的,努力的人 laekov 曾经或许有自己的梦想 直到那一天,在那个体育馆里,在那台显示器前面,一切都改变了,结束了 laekov 记得那个暑假的某一天,他在床上躺了一整天没有起 或许之后的十年都只是那个夏日的白日梦而已 得过且过成为了人生的主旨 或许随时终结这一切都无球所谓 或许兴致来了可以创造些美好的东西 再或许随手一巴掌拍过去毁灭它 又能怎么样呢 有什么是不能失去的呢 这个世界上也许冈崎朋也永远不会遇到古河渚 即使遇见了,就获得了真正的美好吗 十年之前,我不认识你,你不属于我 十年之后,不再是朋友,不可以问候 —- 来自十年之后的没有逻辑没有思想胡乱骂街的 laekov laekov 或许早已不是 laekov 了 这只是一具掌管着 laekov 账号的空空的躯壳罢了 没想到这是 2025 年第一次写博客 laekov 还欠着两篇 blog HypeReca 的中文版 What does it take laekov to get the PhD degree 或许最近补完这两篇文章之后 就该是 laekov.com.cn 永远停止更新的时候了
LLM Serving 文章阅读笔记
经典老文 orca Continuous batching: 把 prefill 和 decode 里的每个 token 打散重新做 batching. vllm 用 page attention 来管理 kv cache 来应对碎片化, 以及利用 cpu memory 来 offload (这部分好像不是重点)。 OSDI'24 一个会有一个 session 一篇文章讲同一个事,可怕。 Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve 背景是现有 llm serving 系统(TRT-LLM, vLLM)要么等 decode 完了再 prefill, 要么有 prefill 就先做完整个 prefill, 导致 latency to first token 或者 decoding latency 不稳定。一个额外的坏处是这个事情影响 pp,因为 pp 里面有多个任务,每个任务时长不一样,就会有比较多的 bubble。 这文章把 prefill 任务 chunk 掉,这样调度的时候可以更好地复合 prefill 和 decode,控制 pp 里每个任务的 latency,从而对 decode 的 latency 也有保障了 (stall-free batching)。...
FastMoE 系统指南
FastMoE 是世界上首个开源的在 PyTorch 上支持 MoE 模型分布式训练的框架. 经过持续不断的更新与优化, 其在性能上相比各类竞品持续保持了一定的优势. 从 2021 年 3 月开源至今, 已经历了若干个发行版本, 亦有一些相关学术工作发表在各大会议和平台上. 此处对官方提供的公开资料进行汇总整理. FastMoE 代码仓库 FastMoE 框架的开源版本开源在 GitHub 上. 链接 该开源版本支持 cuda 平台. 开源版本中也包含来自社区贡献的对 rocm 平台的支持, 但对新版本 FastMoE 的支持可能并不完善. 此外, 对于申威和一些其它国产加速平台, FastMoE 也有相应的私有版本. 如有兴趣, 请联系清程极智. FastMoE 使用方式 FastMoE 作为 PyTorch 的插件存在, 推荐的使用方式是和 Megatron-LM 框架一起使用. 开源版本代码仓库中提供了修改不同版本 Megatron-LM 并与 FastMoE 一起使用的教程和参考补丁. 在FastMoE 官网(暂停维护)和代码仓库的中有更多文档可供参考. FastMoE 及系列学术文章 FastMoE 支持专家并行的工作原理在一篇 arxiv 文章中进行了讲解. arxiv原文 中文博客版本. FasterMoE 是一个发表在 PPoPP 学术会议上的工作. 其对于专家并行中负载均衡和通信计算重叠进行了研究. 该论文中所述的优化均已集成到 FastMoE v1.0.0 以后的版本中....
在 PyTorch Distributed 中混合使用 mpi 和其它 backend
laekov 遇到的问题是希望使用 mpi 进行一些 cpu 的通信, 以及用 nccl 来进行一些 gpu 间的通信. // 没错, 说的就是让 FastDecode 支持模型并行. 众所周知, pytorch 和 mpi 的关系不太好的亚子. 然而 mpi 其实是最方便, 也是最适合大规模使用的. 虽然新版的 pytorch 试图引入 ucc backend 来支持 cpu 和 gpu 的混合通信, 但在较老的版本或一些特定环境里还无法顺畅地使用 ucc. 事实上 pytorch 支持创建不同 backend 的不同 ProcessGroup. 然而如果写如下一段代码, 就会发现并跑不起来. dist.init_process_group(backend='mpi') ... g = dist.new_group(list(range(world_size)), backend='nccl') x = torch.ones(16, device='cuda') * (rank + 1) xs = [torch.empty_like(x) for _ in range(world_size)] dist.all_gather(xs, x, group=g) 甚至会获得一些在 ucx 里的错误栈, 再往上找会发现报错在 c10d::PrefixStore::set 这个函数里....
FastDecode: 一种很大胆的分布式 LLM 推理系统架构
这是一篇 arxiv 文章 的中文简要版本. 摘要 这篇文章主要介绍了一种大语言模型的推理系统. 在自回归生成过程中, 序列中的元素 (token) 被挨个生成, 因此模型推理的序列长度 (sequence length) 为 1. 因此, 增大 batch size 对于 GPU 利用率的提升十分重要. 然而 KV-Cache 体积很大, 且与 batch size 成正比. 其大小阻止了 batch size 和 GPU 利用率的提升. 相比 vLLM 提出的 page attention 技术, FastDecode 对于 CPU 的利用进行了更加大胆的尝试. 其不仅利用了 CPU 的内存容量, 还利用了其计算能力和多机扩展能力, 从而达到了提升 batch size, 提升 GPU 利用率的目的, 并实现了端到端的推理吞吐量提升. 背景 在自回归生成过程中做 attention 时, 一个 token i 的特征向量 (feature vector) 会线性映射拆成 Qi, Ki, Vi 三个特征向量....
实验室新机器安装步骤检查单
本检查单适用于在 PACMAN 实验室 安装新的服务器. 对于其它使用场景, 可视情况进行参考. 购买前 根据使用需求确定型号 PCIe 的连接方式是否符合预期 内存通道是否充足 在机房寻找一个合适的位置来放置机器, 需考虑如下因素 机柜的空位与承重能力 电源是否充足 网络 (如需使用 IB 网, 与需要的交换机是否足够近) 根据 CPU arch 确定是否接入某个 slurm 进行管理 现有的 slurm clusters: ja (AMD Epyc), nico (Intel Skylake) 注意: 除非这台机器永远只有一个人使用, 否则强烈建议接入 slurm 进行管理 起一个合适的 Hostname 向网络管理员申请一个合适的固定 ip 机器上架与硬件配置 (机房内) 检查机器完好 正确安装导轨 对机器的整体外观, 序列号进行拍照 插入系统盘和必要的存储, PCIE 设备 注意: 插入额外的 GPU 资产也需要事先对序列号和整体进行拍照 根据分配的固定 IP 配置 BMC 机器基础配置 (可远程) 在 NetBox 上更新相应信息, 包括但不限于序列号, 资产号, GPU 在 BIOS 中配置 CPU Sub-numa Clustering 以确保访存性能正确 Intel 简称 SNC, AMD 简称 NPS 可能在 ACPI 或 North Bridge 选项中 (视型号不同) PXE 引导安装 OS 机器软件配置 安装必要的基础软件 htop iotop iftop vim-common numactl rsync psutils ipmitool g++ 根据 Harry 的教程 配置 LDAP Client 安装 libnss-ldapd 和 libpam-ldapd 配置正确的服务器地址, base dn 和 LDAP 数据项 安装 nfs 客户端 安装 nfs-client nfs-common 挂载对应的 /home 配置 slurm 客户端 安装 libmunge-dev libmunge2 munge slurmd slurm-wlm libpam-slurm-adopt libpam-slurm libpmix-dev libpmi2-0 libpmi0-dev libpmi0 将主节点的 munge key 同步到新机器 /etc/munge/munge....
本网站的崩溃与重建
由于升级系统升挂了(说来话长…) 原本跑在青岛阿里云 ecs 上的 shiruku 无了. 于是决定迁移到 Hugo. 目前姑且能用了, 且保留了之前的大部分内容. 之后还会继续修缮. 顺便开个坑记录一下这次的经历. 升级然后挂了 在 12 月 5 号这一天, laekov 看到自己的青岛阿里云服务器还跑着 ubuntu 18.04 (i686), 于是决定对它进行一个 dist-upgrade. (好像也没啥原因) 没想到 do-release-upgrade 说没有新的版本, 于是 laekov 直接在 sources.list 里把 bionic 换成了 jammy, 然后愉快地 apt update / upgrade 了一顿. 然后疑似 kernel 还是 4.19, laekov 感到疑惑, 但是没多想就重启了机器. 没想到重启之后服务器 ping 不通了, 还好 aliyun 提供了 vnc, 连过去一看 kernel panic, 读不出镜像. 还好重启之后发现有一个旧的 kernel 可以启动, 于是和 harry 一拍脑门, 决定跑一遍 initramfs, 然后这下好了, 新的旧的都启不动了....
CentOS 的防火墙和 ldap login
最近在实验室遇到一些情况必需搞一台 centos 的服务器, 但是还是想给它配置我们常用的一些东西, 于是踩了一些坑, 作一个记录. sshd 在别的端口 我们用这个来提供外网的仅公钥的访问, 然而 cent 里面配了 sshd_config 里的 port 之后竟然没法从别的机器访问到这个 port. 关掉 selinux 也没用, 最后发现需要 disable firewalld. (什么企业级安全) sssd ldap 无法 auth 相比 debian 底下使用 libnss-ldapd 和 libpam-ldapd, cent 下面用的是一个叫 sssd 的玩意. 然后使用 authconfig 来进行配置. 然而配好了之后可以 id 一个用户 , 却不能 getent. 发现需要在 sssd 配置文件里加上这个. enumerate = true 然而还是无法用 ldap 用户密码登录, 一通查发现是因为 SSSD always uses an encrypted channel for authentication, which ensures that passwords are never sent over the network unencrypted....
魔改 python-dbg
最近在一些奇怪的地方使用 pytorch. 那里的 python 十分的鬼畜, 以至于 python-debug 用不了. c 的栈打出来大概是这样的. #110 0x00004ffff061c03c in _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>) at ../Python-3.6.8/Python/ceval.c:3351 #111 0x00004ffff061865c in PyEval_EvalFrameEx (f=0x6, throwflag=8387296) at ../Python-3.6.8/Python/ceval.c:754 #112 0x00004ffff06192fc in _PyEval_EvalCodeWithName (_co=0x58000044c980, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=0, kwnames=<optimized out>, kwargs=0x58000d8621b8, kwcount=2, kwstep=1, defs=0x580000449340, defcount=2, kwdefs=0x0, closure=0x0, name=0x5800003431c0, qualname=0x5800003431c0) at ../Python-3.6.8/Python/ceval.c:4166 #113 0x00004ffff0619768 in fast_function (kwnames=<optimized out>, nargs=0, stack=0x58000d8621b8, func=0x58000296f6b8) at ../Python-3.6.8/Python/ceval.c:4992 #114 call_function (pp_stack=0x500000804400, oparg=<optimized out>, kwnames=<optimized out>) at ....