Hi there 👋

Welcome to my blog, my name is Ray. I am a software developer and this is my personal blog where I share my thoughts, experiences, and projects. Feel free to explore and connect with me!
杂技浅尝

25GB 内存就能跑 GLM-5.2?我在 RTX 3060 上实测了 744B MoE

先说结论:能跑是真的,能不能用是另一回事,别抱太大期待。 在我的 RTX 3060 开发机上,GLM-5.2 744B 最终跑到了约 0.44 tok/s。工程上挺有意思,但离正常聊天还差得远。 最近看到一个挺吸引眼球的项目:JustVugg/colibri。 这个词是蜂鸟的意思,借自法语 colibri,源自一加勒比语言。 它的介绍很直接: Run GLM-5.2 (744B MoE) on a 25GB-RAM consumer machine. 744B 参数、25GB 内存、纯 C、零依赖,剩下的专家权重直接从磁盘读取。 刷到这个项目就觉得有意思,因为我本地的开发机也能跑(之前 KTransformer 也想跑,无奈服务器跑着一些业务一直腾不出来),要是这个项目能跑出个位数的 decode 速度就发了哈哈哈。但是 README 看了一圈就明白我的美梦破碎了,话不多说,先看我的折腾记录。 我有一台常用的开发机,已经被我虚拟化,把一台已经跑 MC 的虚拟机清掉,把 CPU、内存和磁盘资源合并到主力虚拟机上,下载了接近 400GB 的模型,真的把它跑了起来。 模型能正常对话,也有 OpenAI 兼容 API,仓库自带的 Brain Dashboard 还能看到 19,456 个专家在推理时不断闪烁。 跑起来是一回事,好不好用是另一回事。文末有在我这个环境实测的 GIF 效果。 我的测试环境 这次测试跑在一台 PVE 里的 Ubuntu 虚拟机上: 项目 配置 系统 Ubuntu 24.04,KVM/QEMU CPU 20 vCPU,AVX2/FMA,无 AVX-512/VNNI 内存 Linux 可见约 39GiB,另有 8GiB Swap GPU RTX 3060 12GiB,PCIe Passthrough 模型盘 500GB QEMU SCSI 磁盘,ext4 模型 GLM-5.2-colibri-int4-with-int8-mtp 模型总大小 383.74GB,共 144 个分片 路由专家 19,456 个,共 372.85GB 实际运行时,进程 RSS 大约在 27GB 左右。测试配置里的 8GB VRAM 和 7GB RAM,指的是固定给热门专家用的缓存层,不是整个程序的总内存占用。 ...

July 17, 2026 · 5 min · 872 words · Updated: July 18, 2026 · Ray
杂技浅尝

人脸识别为什么要眨眼还要闪各种颜色的光

今天办业务需要人脸识别,拿起手机把我的小胖脸放入框中眨眨眼,等待灯光闪烁,随后就是通过,这个已经见怪不怪了,偶尔还要张张嘴,左右摇头,我知道他这是在确认我是不是真人,但是哪怕我做过简单的人脸识别,我也没有深究过人脸活体检测具体有多少方法,以及闪光是在干嘛,本文对此做了调研和解释。 差不多在 23 年有一个小项目,要做离线人脸识别来替换百度人脸识别 API。没太多性能要求,我搜刮来一个 facenet-retinaface-pytorch 仓库,扒拉两下就集成进系统了。 这个仓库只需要把人脸向量存起来,再把新照片转换成向量做对比。底层不用懂也能跑通,后来需求搁浅,我也就没有继续深究。 首先,人脸识别是怎么实现的 不展开神经网络和数学公式,整个过程可以粗略分成三步。 摄像头拿到画面后,先找到人脸的位置,把脸裁出来并校正角度;接着模型把五官、轮廓和纹理压成一串数字,也就是人脸向量;最后,把这个向量和之前保存的向量计算相似度。 相似度超过阈值,系统就认为两张脸可能属于同一个人。阈值越严格,冒认更少,但真人也更容易被拒绝。 所以,人脸识别主要回答的是“这张脸像谁”,而像谁并不能代表眼前真的就是谁。一张照片、一段视频,照样能提取出很像的人脸向量。 为什么要做人脸活体检测以及怎么做 当然,不做活体检测的话,拿张照片或者播放一段视频就可能通过人脸比对。它要补上的问题是:镜头前的东西,究竟是现场真人,还是照片、屏幕、面具或被替换的视频流。 来点专业词汇,活体判断可能会组合随机挑战、RGB 纹理与时序、深度或红外、材质与光反射、可信采集链路和服务端风控。一下子就懵了,还是先从我最早的两个问题说起。 眨眨眼是干嘛的 最早、最直观的用途,是排除一张不会动的静态照片。系统连续观察眼睛,如果看到“睁开—闭合—再次睁开”的时序,就认为镜头前至少不是一张完全静止的普通照片。 系统通常会在每一帧里定位眼角和上下眼睑,计算眼睛高度与宽度的比例。这个数值短时间内从高变低、再变高,就很像一次眨眼。现代模型可能直接输出眼睛开合概率,原理差不多。1 如果系统临时提示“现在眨眼”,它还构成了一次简单的挑战—响应:系统刚发出要求,用户随后作出动作。这比静静等待一次自然眨眼,多了一点“正在发生”的证据。 但它的证明力有限。视频中的人也会眨眼,挖掉照片的眼睛区域也能模拟眨眼,实时换脸则可以直接跟随攻击者的动作。眨眼能对付普通照片,却不能单独对付视频重放。2 屏幕颜色变化是干嘛的 在典型的活体认证实现里,手机屏幕被临时当成了一个可编程光源。系统随机生成一串颜色、亮度或图案,让它们依次照到脸上,同时让前置摄像头记录脸部反射。颜色不是主要让人去识别、记住或回答;真正“回答问题”的是脸对光的即时反射。 它想核对三件事: 时间是否对得上。 本次认证临时生成的随机颜色序列,相当于一次性口令。脸上的颜色变化必须紧跟本次序列,不能是过去录好的一段固定画面。 空间形状是否像人脸。 鼻尖、眼窝、额头、面颊朝向不同,受到同一块屏幕照明时会出现不同的明暗分布。普通照片或显示屏是近似平面,反射分布不同。 材料是否像皮肤。 皮肤、纸张、玻璃屏和硅胶面具的反光方式不一样,模型会尝试找出这些差异。 2018 年的 Face Flashing 研究系统化提出了这种做法:屏幕随机闪现颜色或图案,再分析脸部反射的时间、纹理和三维形状。3 AWS 的商用活体服务也提供“面部移动 + 彩色光序列”的模式。4 当然,屏幕变色也可能兼有曝光、白平衡校准,甚至只是界面效果。只看页面闪了几下,无法确定某个 App 到底用了哪些模型。 如果我用一段眨眼视频会怎么样 答案是:有可能,但取决于系统检查到了哪一层。 只检查有没有眨眼: 预录视频本来就有“睁—闭—睁”,存在通过的可能。 还检查屏幕重放痕迹: 系统会寻找摩尔纹、屏幕刷新、玻璃反光、二次压缩和平面运动,视频就没那么容易过。 再加随机光、深度或红外: 固定视频不知道本次颜色序列,普通屏幕也缺少真实人脸深度,通过难度会进一步提高。 还有一种更危险的情况,是不拿屏幕对着摄像头,而是直接用虚拟摄像头或修改 App 的相机画面。这已经不只是活体算法的问题,还需要系统确认视频确实来自可信的真实摄像头。 最后 人脸识别回答“这张脸像谁”,眨眼检查“画面里的脸有没有做动作”,随机变色则检查“这张脸有没有立刻响应本次随机光”。可靠的系统不会只押宝其中一项,而是把多种线索放在一起判断。 Soukupová, T.; Čech, J., Real-Time Eye Blink Detection using Facial Landmarks, 2016. https://vision.fe.uni-lj.si/cvww2016/proceedings/papers/05.pdf ↩︎ A Survey on Anti-Spoofing Methods for Facial Recognition with RGB Cameras of Generic Consumer Devices, Journal of Imaging, 2020. https://doi.org/10.3390/jimaging6120139 ↩︎ ...

July 17, 2026 · 1 min · 117 words · Ray
杂技浅尝

vLLM + Qwen3.6 视频推理踩坑记录

vLLM + Qwen3.6 视频推理踩坑记录:AV1、OpenCV 与视频采样问题 Info 之前 qwen3.6-27b 模型发布后没多久我就部署他 并且测试过视频能力,一直是公司内部署的主力离线大模型。 所以我认为一直可用,但是今天同事提了个新的需求,要从视频中找出属于广告部分的内容裁剪掉。我首先给出的方案是 用 Qwen3-ASR+Qwen3-ForcedAligner 模型来获取 文本内容以及时间轴,再用 LLM 来判断哪些文本属于广告内容,随后根据文本所对应的时间轴裁剪视频,先这样子给同事搭建了环境让他去跑几个试试,同时我来试试直接让 qwen3.6 读视频是否可行。结果一来就给我个报错 环境 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Model: Qwen3.6-27B BF16 vLLM: 0.19.1 Transformers: 5.6.0 Python: 3.12 4*RTX 3090 24GB 显示已折叠代码(18 行) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 启动参数: vllm serve /data/huggingface_model/Qwen/Qwen3.6-27B \ --served-model-name qwen3.6-27b \ --port 13539 \ --tensor-parallel-size 4 \ --max-model-len 65536 \ --reasoning-parser qwen3 \ --enable-auto-tool-choice \ --tool-call-parser qwen3_coder \ --gpu-memory-utilization 0.90 \ --max-num-seqs 4 \ --enable-prefix-caching \ --enable-chunked-prefill \ --disable-custom-all-reduce \ --allowed-local-media-path /<指定目录> \ --media-io-kwargs '{"video":{"num_frames":64}}' \ --mm-processor-kwargs '{"fps":1,"do_sample_frames":false}' 这里的 --media-io-kwargs 是给 vLLM 多模态视频读取器传额外参数的。video.num_frames=64 表示整段视频送进模型前目标采样 64 帧,不是每秒采样 64 帧。比如一个 10 秒、25 FPS 的视频,原本大约有 250 帧,最后会在整段视频的时间范围内均匀取 64 帧,平均下来大约相当于 6.4 FPS。 ...

July 16, 2026 · 3 min · 606 words · Ray
什么是什么

什么是 CUDA:用 Java 世界的类比看懂 Driver / Toolkit / PyTorch / Conda

AI 开发配置 conda / cuda / pytorch / nvidia-driver 很容易混淆,让人头疼,实际上踩过几次坑就能摸清它们的概念和关系了。本文尝试用 Java 开发者熟悉的语言,对照解释几个常见概念。 GPU 世界 Java 世界 作用 GPU 硬件 CPU 真正执行计算 NVIDIA Driver JVM(HotSpot) 控制硬件、执行程序 CUDA Toolkit JDK 给开发者写程序用 nvcc javac 编译器 libcudart.so Java Runtime Library 运行时库 cuBLAS/cuDNN Netty、Apache Commons 等第三方库 提供高性能计算能力 PyTorch Spring Boot 应用框架 conda SDKMAN / Maven + 环境管理 管理版本 下面一点一点讲。 第一层:GPU Driver(最重要) 先理解一件事:GPU 本身不会执行 CUDA C++。 GPU 最终执行的是一种叫做 SASS 的机器码。 整个过程实际上是: ...

July 14, 2026 · 4 min · 697 words · Updated: July 15, 2026 · Ray
人间报错

chatgpt 你不打算 chat 了吗

自从更新 chatgpt 和 codex 之后,我手贱的把 chatgpt classic 给卸载了,现在找不回来了,我怀念我的 option+space openai 是不打算继续服务普通 chat 用户了吗,或者应该把那个功能恢复吧 2026 年 7 月 14 日 21:35:28 哦哦 找到解决方法了,mac 用户可以直接用 homebrew 安装回来 brew install --cask chatgpt-classic 2026 年 7 月 14 日 21:47:06

July 14, 2026 · 1 min · 36 words · Ray