GCC 中的 whole-archive 参数解析
本文由 AI 加提示词大纲生成 提示词如下: 帮我写一篇博客,介绍 gcc 中的 whole-archive 这个参数,顺序如下: 背景:使用全局变量动态注册类到 RegisterFactory 中的时候,发现这个库打包为静态库时,可执行文件去链接这个静态库,会出现未注册成功的情况 表现:1、保存注册结果的 map 大小为 0;2、文件非常小,仅有十几KB,看起来并不包含整个静态库;3、访问空指针时会导致段错误;4、使用动态链接库时没有问题 原因:当全局参数被注册在静态库中时,如果这个静态库被链接,会导致静态库中的全局参数被优化掉了,也就没有注册成功 解决方案:使用 -Wl,--whole-archive lib -Wl,--no-whole-archive 使得链接器在链接时不要优化掉全局参数 在使用全局变量动态注册类到 RegisterFactory 时,常常会遇到这样一个问题:当库打包为静态库后,最终生成的可执行文件链接这个静态库,却无法正常注册。这篇文章将详细介绍这一问题的背景、表现、原因以及解决方案。 1. 背景在很多项目中,我们会在全局作用域中注册类到工厂(R...
科目二考试 - 00
科目二考试有关科目二的一些信息和内容分享。 一般来说,科目二教练在开始练习时让学员最先做的两件事就是:调整座椅和后视镜。这两件事其实都是为了点位这个概念服务的。 至于为什么需要【点位】?原因还是科目二考试需要一次性倒车入库成功,中间不可以换挡,例如从倒车档换成前进档,如果发生换挡,这次考试就挂了。为了方便教学,总结出了点位这个概念。 在座椅确定之后,空间位置就确定了。在这种情况下,记住在何时倒车、何时回正方向盘,就可以一把实现倒车入库了。所以,点位其实就是时间点在车辆空间中的位置。 座椅 座椅的调整是为了确定 3D 空间中的位置,用 3 个距离来描述我们的坐姿,从而在考试的时候复现这个位置。3 个距离如下: 大拇指:手臂水平伸直,大拇指的根部位于仪表盘罩上 头顶:头顶距离车顶 4 指高(一拳) 膝盖:距离前方 3 指宽 后视镜点位上面的两点都是为了【点位】这个概念服务的。
记一个关于 RMSNorm 实现上的细节
背景在 RMSNorm 的实现中,都会强制把输入转为 float32 再进行计算,主要为了避免在计算过程中出现溢出的情况,特别是 float16。 bfloat16 由于动态范围更大,通常不会出现溢出问题,但在一些特定的计算场景下,仍然可能会遇到精度问题。因此,在实现 RMSNorm 时,强制转换为 float32 是一个通用的做法。 RMSNorm123456789101112131415import torchimport torch.nn as nnclass RMSNorm(nn.Module): def __init__(self, dim, eps=1e-8): super(RMSNorm, self).__init__() self.weight = nn.Parameter(torch.ones(dim)) self.eps = eps def forward(self, x): # 强制转换为 float32 x = x.to(torch.float32) # 计算 ...
Qwen2.5-VL 中视觉模型的窗口注意力机制
背景在算能的 LLM-TPU 里有对 Qwen2.5-VL 视觉模型的导出,但是并没有增加对窗口注意力的支持,因此跟 Qwen2.5-VL 原生相比,性能下降较大。 UPDATE: 算能官方已经支持 qwen2.5-vl 的窗口注意力,具体实现参考 tpu-mlir/llm。 qwen2.5-vl 视觉编码器的注意力机制qwen2.5-vl 中有两种不同的注意力机制: 全局注意力:用于处理全图特征,但是计算量较大,计算量增长随着图像尺寸的增加而呈平方增长,因此只在 4 个特殊的 layer 使用。 窗口注意力:只计算局部区域的注意力,计算量较小,适用于大多数层。 qwen2.5-vl 的视觉编码器注意力计算如下: 1234567891011121314151617181920212223class Qwen2_5_VLVisionFlashAttention2(nn.Module): ... def forward( self, hidden_states: torch.Tensor, cu_seqlens: t...
论文总结 | Next Token Prediction Towards Multimodal Intelligence A Comprehensive Survey
背景文章介绍了截至 2024 年,多模态大模型的进展。文章从词元化(tokenization)、骨干网络(backbone)、训练方式(training)、数据集(dataset)四个方向进行总结,并给出了多模态模型的未来发展方向及挑战。这对于我们了解和部署多模态大模型非常有帮助。 同时,本文主要是梳理相关基础内容,暂不对论文中给出的所有参考文献做详细解析,仅对关键点进行总结。 模型流水线组成 这张图主要分为三个部分: Tokenization是将输入数据转换为模型可以处理的形式的过程。图中展示了两种类型的词元化: Discrete Tokens:输入图像通过Encoder转换为特征表示,这些特征表示通过Vector Quantization过程转换为离散的词元(如数字7、2、9等)。为了确保词元的生成质量,离散词元在训练阶段还需要通过Decoder转换回图像。 Continuous Tokens:输入图像同样通过编码器转换为特征表示。这些特征表示通过Projector转换为连续的词元。 Modeling部分展示了Transformer模型的内部结构及其工作原理: De...
Self-Attention 算法简介
MHA MQA GQA 对比MHA Multi-Head Attention,MQA Multi-Query Attention,GQA Group-Query Attention。在 transformers 中,主要体现在 config.json 里的 num_key_value_heads 设置上。 QKV shape 如下: Query: $[B, L, D_{\text{model}}]$ -> $[B, L, N_\text{heads}, D_\text{head}]$ -> $[B, N_\text{heads}, L, D_\text{heads}]$ Key & Value: $[B, L, D_\text{kv}]$ -> $[B, N_\text{kv}, L, D_\text{head}]$ 其中,$B$ 表示 batch size,$L$ 表示 sequence length,$D_\text{model}$ 为 hidden size,$N_\text{heads}$ 为 num heads,即多头注意力里的头数。 re...
Kokoro 模型结构分析&部署
出发点kokoro 是一个 82M 的 TTS 模型,在 TTSArena 上排名第二。基于之前在 MiniCPM-O-2_6 模型结构介绍 上的基础,我们分析一下 kokoro 模型结构,尝试完成 Feature Request: Add support for Kokoro TTS | llama.cpp 这个 issue。 注意到,sherpa-onnx for Kokoro 已经提供了 ONNX 实现,我们可以基于这个模型文件对模型结构进行观察。
ONNX 静态图转换为动态图
模型转换ONNX 模型从动态图变为静态图是非常容易的,使用 onnxsim --overwrite-input-shape input_name:dim0,dim1,dim2 model.onnx 即可,onnxsim 内部会将动态维度转为静态维度,同时执行图优化。 但是如果只有静态图,想要变回动态图,则比较困难。一般来说,Batch 维度是最容易改变的,修改 Batch 维度可以一次推理 N 个输入,提高吞吐量。 使用 onnx2torch 可以解决这个问题。首先将 ONNX 模型转为 pytorch 模型,然后重新使用 torch.onnx.export 导出一个有动态维度的模型即可。代码如下: 1234567891011121314151617181920import onnximport torchfrom onnx2torch import convert# onnx -> torchonnx_model_path = "/some/path/mobile_net_v2.onnx"torch_model_1 = convert(onnx_mod...
CPU 忙等的死锁案例
一个死锁案例代码部分逻辑: 1234567for (int i = tid; i < work_size; i += thread_num) { while (is_work_ready[i] == 0) { // spin lock } // do work foo(work[i]);} 下面这段代码看起来是合理的,线程执行的状态依赖于 is_work_ready[i],通过这个变量实现主线程和子线程之间通信。但是实际上由于 CPU 会陷入忙等(busy-waiting),导致当主线程更新 flag 之后,子线程不会读取这个变量,陷入死锁。即「如果 is_work_ready 为 1,正常执行」,但是「is_work_ready 为 0 时,陷入死锁,无法恢复」。 有关多线程编程的方式: 如果代码涉及到主线程与子线程的通信,最好使用同步 API,不要使用简单的 dead loop 。比如 ChatGPT 建议使用 std::mutex + std::conditional_variable 通信。 dead lo...
MiniCPM-O-2_6 模型结构介绍
目的介绍一下有关 VLM/MLLM 的模型结构,从模型结构上指导模型部署,了解各个模块的作用。 MiniCPM-O-2_6 简介O 代表了 Omni,含义是全能。MiniCPM-O-2_6 是一个基于 MiniCPM-2 的多模态模型,在之前的 MiniCPM-V-2_6 的基础上增加了额外的多模态能力,包括【语音识别】、【语音生成】的功能。由于语音作为文本嵌入到了 LLM 的输入之中,还可以实现【语音提问图片内容,语音回复】的功能。OpenBMB 官方博客见 MiniCPM-o 2.6: A GPT-4o Level MLLM for Vision, Speech, and Multimodal Live Streaming on Your Phone。 为了实现上面的功能,MiniCPM-O-2_6 一共有四个模块: SigLip-400M 视觉编码器:用于提取视觉特征,并映射到 LLM 嵌入空间 Whisper-medium-300M 语音编码器:用于提取语音特征,也映射到 LLM 嵌入空间 LLM:基于 Qwen2.5-7B 模型,能够支持多模态输入,但是受限...