CodingTour
ARTS #219 | 神兽回家

再一次,一个人坐飞机回来了~

Algorithm

本周选择的算法题是:Gray Code

class Solution:
    def grayCode(self, n: int) -> List[int]:
        return [i ^ i >> 1 for i in range(1 << n)]

历史上用过的一种编码,是一种特殊的二进制编码方式,其中两个连续数值的编码仅有一位不同,如 Gray Code 的 3、4 表示:

  • 3,010
  • 4,110

编码思路是:

  1. 保留最高位不变
  2. 从第二高位开始,每一位与其前一位进行异或运算

例如,将 1011 转换为 Gray Code:

  1. 保留最高位 1
  2. 第二高位 0 与最高位 1 异或,结果为 1
  3. 第三高位 1 与第二高位 0 异或,结果为 1
  4. 最低位 1 与第三高位 1 异或,结果为 0

所以,二进制 1011 对应的 Gray Code 是 1110

右移一位再异或则是此思路的完美实现。

Review

Why Nvidia’s AI Supremacy is Only Temporary

作者分析了 Nvidia 如今取得优势的原因:

  1. 机器学习的发展与研究依赖大型科技公司,其他多数公司仍在研究如何使用这些新功能,因此相比推理,机器学习更专注于训练
  2. Nvidia 的替代品们不够成熟,竞争对手没有有效的方法可以击败 Nvidia 建立的平台效应,当前市场赢者通吃是有道理的
  3. 研究人员拥有购买力,研究人员的招聘、留任成本非常高,在购买硬件时,他们的偏好被放在非常高的优先级上
  4. 训练的迭代周期有限,基于 Nvidia GPU 几乎总是可以做到在相同的训练时间内(比如一周)构建出更大的模型,训练周期(也就是迭代周期)很重要,竞争对手看似有机会以更低的时延取胜,但几乎不可能,CUDA 已有数十年的积累

但这些情况有可能会发生改变:

  1. 推理将占主导地位,而不是训练,“训练成本与研究人员的数量成正比,推理成本与用户的数量成正比”,世界上有大量的潜在用户,面向用户的应用程序延迟是关键影响因素之一,需要采用截然不同的优化方法。还有很多东西(比如权重)在推理过程中保持不变,因此可以从权重压缩或常数折叠等预处理技术中优化
  2. CPU 在推理方面具有竞争力,CPU 算术操作的成本比 GPU 便宜得多,而且开发工具和社区更成熟,对于推理而言,模型权重是固定的,并且可以在初始化时轻松地在多台机器上复制,因此不需要通信
  3. 部署工程师的优先级将被提高,出于降低成本的压力,推理成本的考虑权重将主导训练过程
  4. 应用程序的成本优先,推理成本占据 AI 预算主导地位时,会产生新的协作方式:模型的作者用专门的工具,比如 Matlab 用于数学算法,然后将结果交给部署工程师,他们将手动将结果转换为对应用程序来说更高效的东西。这很有意义,因为如果模型架构保持不变(即使权重发生变化),任何成本的节省都会在很长一段时间内长期受益
作者 Pete Warden 是 [JetPack SDKNVIDIA Developer](https://developer.nvidia.com/embedded/jetpack) 的作者,他预测 x86 和 ARM 等传统 CPU 平台将会是这一转变的赢家,在不产生延迟的前提下,将推理紧密集成进传统的业务逻辑中以运行最终面向用户的应用程序,而 CPU,可能会像支持浮点运算那样,通过协处理器、专用指令支持机器学习。

Tip

一段从 redis 导出指定规则 key 数据的脚本:

#!/bin/sh -eu
command="redis-cli -h r-bp1yd55xip7qhx7sf0.redis.rds.aliyuncs.com -p 6379 -a cmvKyoYP13kI1m1D -n 10"
keys=`$command keys '*_doing'`
if [ "$keys" ]; then
    echo "$keys" | while IFS= read -r key; do
        type=`echo | $command type "$key"`
        case "$type" in
            string) value=`echo | $command get "$key"`;;
            hash) value=`echo | $command hgetall "$key"`;;
            set) value=`echo | $command smembers "$key"`;;
            list) value=`echo | $command lrange "$key" 0 -1`;;
            zset) value=`echo | $command zrange "$key" 0 -1 withscores`;;
        esac
        echo "> $key ($type):"
        echo "$value" | sed -E 's/^/    /'
    done
fi

Share

Matte Anything 初体验。

主要思路是,首先通过 SAM 根据用户输入对图片进行分割并生成 trimap,然后用 trimap 引导 VitMatte 进行 alpha matting。

上图算是一张比较好的 good case,学术界的 demo 通常到工程化还有不少距离,交互、时延、资源使用率等等优化不少,拿这个 MAM 来说,它的显存使用惊人,1k 的图,要 15GB 左右 VRAM,但其实这些模型(MAM 依赖三个模型)并不是并行使用的,不应该占用这么多 VRAM,此处有很大的优化空间。

demo 的过程记录,再一次感受到学术界对开源项目的维护缺乏长期支持…

  • numpy 要用 1.x,不然不兼容;别头铁,升到 2x 的话要改的地方太多了
  • 在 Python 3.10 下(用 3 年前的版本,不过分吧),opencv 要用 4.5.4.60,不然编译不了
  • opencv-python-headless 要用 4.5.5.64
  • 最新的 GroundingDINO 使用的是 cuda 11.8,延伸出 pytorch 要用 2.0.1、torchvision 要用 0.15.2
  • 在多 GPU 上 cuda 会报错,需要安装 mmcv 并调整部分源码 mmcv

和工程界维护开源项目的初衷隐隐有些不同:

  1. 工程界是希望大家能直接用,并且兼容性方面,会花很大的成本支持各种平台、框架、系统,但用起来简单易用
  2. 学术界是希望大家能吸收想法,不建议直接使用,而是像白盒一样融入到自身的项目中,成为其中的一部分