前言 今天做了 UVA12538 自带版本控制功能的IDE Version Controlled IDE 看了下题解发现可以用 rope 直接水过,所以发篇博客,记录一下 rope 的用法。 简介 rope 的本质就是块状链表。 rope 是 C++ STL 中 pbds 的一个分支,想要引用,需要加上两行代码: #include <ext/rope> using namespace __gnu_cxx; rope 可以实现在 define CI Cn int& #define gc getchar #define D isdigit(c=gc()) #define pc(c) putchar((c)) #include <ext/rope
环形缓冲区(ring buffer),环形队列(ring queue) 多用于2个线程之间传递数据,是标准的先入先出(FIFO)模型。一般来说,对于多线程共享数据,需要使用mutex来同步,这样共享数据才不至于发生不可预测的修改/读取,然而,mutex的使用也带来了额外的系统开销,ring buffer/queue 的引入,就是为了有效地解决这个问题,因其特殊的结构及算法,可以用于2个线程中共享数据的同步,而且必须遵循1个线程push in,另一线程pull out的原则。
BUPT2017 wintertraining(15) #8E 题意 image.png 题解 image.png 代码 #include <cstdio> #include <ctime> #include <algorithm> using namespace std; typedef long long ll; const int Times=10; ll gcd(ll a, ll b){ while(b){ ll t=a%b; a=b; b=t; } return a; } ll
旋转编码RoPE 1.1 基本概念 在介绍 RoPE 之前,先给出一些符号定义,以及基本背景。 1.5 RoPE 的高效计算 由于 的稀疏性,所以直接用矩阵乘法来实现会很浪费算力,推荐通过下述方式来实现 RoPE: 其中 是逐位对应相乘,即计算框架中的 运算。 从这个实现也可以看到,RoPE 可以视为是乘性位置编码的变体。 RoPE实验 我们看一下 RoPE 在预训练阶段的实验效果: 从上面可以看出,增大序列长度,预训练的准确率反而有所提升,这体现了 RoPE 具有良好的外推能力。 RoPE代码实现 Meta 的 LLAMA 和 清华的 ChatGLM 都使用了 RoPE 编码,下面看一下具体实现。
但奇怪的是,使用 RoPE 的 LM 依然难以直接在训练长度之外起效,必须依靠其他算法(如 YARN)来辅助其进行外推。 那么,到底是什么限制了 RoPE 的周期延拓,进而限制了 LM 的长度外推呢? RoPE 带来的周期性延拓受到了频谱破坏的影响。 所以,RoPE 周期延拓性的起效前提是 “Hidden States 的每一维只存在单一频率的语义”。 遗憾的是,在使用 RoPE 的 LM 中,这个假设只在 LM 的第一层中成立,但在后面的所有层中都不成立。
旋转位置编码 (RoPE)? RoPE 代表了一种编码位置信息的新方法。传统方法中无论是绝对方法还是相对方法,都有其局限性。 这确保了角度以及这些向量之间的点积保持恒定 RoPE 的矩阵公式 RoPE的技术实现涉及到旋转矩阵。 最主要的是RoPE是可以外推的,也就是说可以直接处理任意长的问题。 在最早的llamacpp项目中就有人通过线性插值RoPE扩张,在推理的时候直接通过线性插值将LLAMA的context由2k拓展到4k,并且性能没有下降,所以这也可以证明RoPE的有效性。 随着我们不断解开语言和人工智能的复杂性,像 RoPE 这样的方法将有助于构建更先进、更准确、更类人的语言处理系统。
MM-RoPE:分布式缩放3D RoPE机制。为优雅解决上述限制,本文提出MM-RoPE——分布式3D RoPE机制。 如前面图2(b)所示,MM-RoPE中文本标记的RoPE遵循标准LLM设计,而视觉标记的RoPE由多个元MM-RoPE组件构成。 首个元MM-RoPE的注意力计算可表述为 其中每个元MM-RoPE组件包含16个通道;其他组件类似定义,共同构成视觉标记的RoPE策略。 MM-RoPE的有效性。下图7(b)展示了0.5B模型在四种RoPE设置下的验证损失。需注意,M-RoPE表示两种设计均被移除。 与M-RoPE类似,MM-RoPE需定位视觉标记起始位置后应用RoPE机制,需少量计算。表4对比了使用标准1D RoPE、M-RoPE和MM-RoPE生成图像和视频的推理速度。
位置组件是单独的投影,对其应用RoPE:q_rope = RoPE(W_qr × c_Q)k_rope = RoPE(W_kr × x)这种分离至关重要:内容和位置被独立表示,仅在注意力分数中组合。 组件 k_rope = self.k_rope_proj(x) q_rope = self.q_rope_proj(q_compressed) = k_rope.view(B, T, self.n_head, self.rope_dim).transpose(1, 2) q_rope = q_rope.view(B, T, self.n_head , self.rope_dim).transpose(1, 2) # 应用RoPE cos, sin = self.rope(x, T) q_rope = apply_rope(q_rope, cos, sin) k_rope = apply_rope(k_rope, cos, sin) # 拼接内容和RoPE
His plan is to attach one end of the rope to the bridge, the other end of the rope to his body and jump The rope's length and strength are good. the rope and is k * Δl, where Δl is the difference between the rope's current length and its Given the rope's strength k, the nominal length of the rope l in meters, the height of the bridge s in For all your calculations, you may assume that James Bond is a point at the end of the rope and the rope
Zed 解析: Rope 和 SumTree Zed是 Rust 构建的文本编辑器, 本文将介绍他的核心数据结构——Rope和SumTree。 Rope和传统字符串比较: Rope是一种二叉树结构,每个叶节点储存一个字符串和其长度,而树上的其他节点则存储所有左子树叶节点长度的总和。 与字符串相比,在编辑大型文件或进行频繁编辑时,Rope更内存和性能高效,因为可以避免大量内存分配和字符移动。 Zed的Rope实现——SumTree: Zed没有选择典型的Rope实现,而是采用了SumTree,这是一种特殊的B+树,允许在O(log N)时间内进行高效的数据遍历。 总结来说,SumTree作为Zed的核心组件,不但具备了常规Rope的优势,还赋予了Zed极高的性能和灵活性,使其成为一个高效的代码编辑器。
虽然旋转位置编码 (RoPE, Rotary Position Embedding) 被广泛用于提升大语言模型的长度泛化能力,但是如何将 RoPE 有效地扩展到多模态领域仍然是一个开放问题。 具体而言,常用的扩展方法是使用 RoPE 中不同的频率来编码不同的位置信息 (x,y,t)。然而,由于 RoPE 中每个维度携带的频率不同,所以存在着不同的分配策略。 那么,到底什么是将 RoPE 扩展到多模态领域的最佳策略呢? 来自 CMU 和小红书的研究团队对这一问题进行了深入研究,他们首次提出了针对多模态 RoPE 扩展策略的理论评估框架,指出现有多模态 RoPE 泛化能力不足的原因之一是保留 RoPE 中所有频率对长上下文语义建模有负面影响 考虑一个长上下文场景,也就是 ,基于语义偏好性质的分析框架可以首先证明为什么在多模态 RoPE 中,使用最低频率建模时间维度(VideoRoPE)要优于最高频率建模时间维度 (M-RoPE)。
RotaryEmbedding # 旋转位置嵌入,应用于每一层 Q 和 K class RotaryEmbedding(nn.Module): def __init__(self, dim, rope_ratio = rope_ratio def forward_impl( self, seq_len: int, n_elem: int, dtype: torch.dtype, 截断到 SeqLen 长度 rope_cache = rope_cache[:sq] # 拆分 X 的最后一维,使元素两个一组,[SeqLen, BatchSize, NHead, HeadSize // 2, 2] rope_cache = rope_cache.view(sq, -1, 1, xshaped.size(3), 2) # 执行旋转编码 # xshaped[ [..., 0] - xshaped[..., 1] * rope_cache[..., 1], xshaped[..., 1] * rope_cache[..., 0] + xshaped
更新日志:https://github.com/console-rs/indicatif/releases/tag/0.17.0 redis-rope Redis 中用于大型字符串的快速且通用的 rope 对于大型字符串,rope 是一种更有效的数据结构,它可以让某些操作的速度快很多: 将字节添加到任何想要的位置。 删除任何 rope 子串或移动到 rope 内的一个不同位置。 将 rope 的任何子串与其他 rope 拼接。 使用随机访问读取任何子字符串。 rope 的背后是 splay tree,这是一种自我调整的数据结构,具有对数摊销的最坏情况性能,而最近访问的索引也可以在后续操作中快速访问。每个展开树节点存储 64 到 127 个字节的数据。 GitHub:https://github.com/ekzhang/redis-rope lemurs 本项目的目标是创建一个小型、健壮且可定制的登录管理器,它可以作为图形 GNU/Linux 的前端。
Sample Input 5 6 1 1 2 3 1 2 2 1 3 0 3 2 1 3 1 2 Sample Output 1 0 1 HINT Source 出题人大SB++ rope 有了rope, 主席树什么的都可以靠边站了, 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath > 5 #include<algorithm> 6 #include<ext/rope> 7 using namespace std; 8 using namespace __gnu_cxx; n=-x:n=x; 17 } 18 19 rope<int> *rp[MAXN]; 20 int a[MAXN]; 21 int n,m,how,x,y,lastans; 22 int find(int { 37 int n,m; 38 read(n);read(m); 39 for(int i=1;i<=n;i++) a[i]=i; 40 rp[0]=new rope
这一改动立刻奏效,缩小了RoPE对远端token的衰减效应,并且在扩展LLAMA的上下文长度上优于一项类似的名为“位置插值”的方法(如下图所示,RoPE PI,衰减效果较为“隐含”)。 Ps. 图中RoPE表示基线方法,RoPE ABF为Meta此次发明的新方法,xPos是另一种应用了该方法的旋转编码变体。 在附录中,Meta还通过可视化为螺旋图这一非常有趣的方式,将RoPE ABF与RoPE PI的差异进行了理论分析。 结果是,与RoPE PI相比,RoPE ABF的优势主要体现在它能以更大的粒度分配嵌入向量(the embedded vectors),从而使模型更容易区分位置。 此外,他们还观察到,嵌入向量之间的相对距离既对RoPE PI的关键参数有线性依赖性,也对RoPE ABF的关键参数也有对数依赖性。 这也就是为什么我们可以很容易地对基频这一超参数“下手”。
每间房间都有一件可疑的物品,可以当作凶器:包(Bag)、火枪(Firearm)、煤气(Gas)、刀(Knife)、毒药(Poison)、绳索(Rope)。 k.Fresh(); var gas = k.Fresh(); var knife = k.Fresh(); var poison = k.Fresh(); var rope var clue1 = k.All( k.Is(kitchen, man), k.Noto(k.Eq(kitchen, rope), k.Eq(kitchen, knife var clue4 = k.All(k.Is(rope, woman), k.Eq(rope, study)); // 起居室里面那件凶器,与 John 或 George 在一起。 点击运行,等待几十秒,输出结果: (bathroom dining kitchen livingroom pantry study bag firearm gas knife poison rope X
The ACM have found that two of the hooks must be connected by a rope that runs through the hooks in every When the rope is fastened, a secret door opens. That means also that the neccessary length of the rope is unknown. Your task is to determine the maximum length of the rope we could need for a given labyrinth. Maximum rope length is 8. Hint Huge input, scanf is recommended.
比如,有研究提出通过位置插值(PI)来稍微修改 RoPE 并在少量数据上微调来扩展上下文长度。 简单来说,RoPE 可以写成如下形式: 对于使用固定上下文长度预训练的 LLM,如果使用位置插值(PI)来扩展上下文长度,则可以表示为: 可以看出 PI 对所有 RoPE 维度都会做同等延展。 研究者发现 PI 论文中描述的理论插值界限不足以预测 RoPE 和 LLM 内部嵌入之间的复杂动态。 这可以通过在应用 softmax 之前将中间注意力矩阵乘以温度 t > 1 来完成,但由于 RoPE 嵌入被编码为一个旋转矩阵,就可以简单地按常数因子 √t 来扩展 RoPE 嵌入的长度。 由于这种 RoPE 插值方案对 RoPE 维度的插值不均匀,因此很难计算相对于扩展度 s 所需的温度比例 t 的解析解。
分别计算RoPE部分和非RoPE部分的注意力分数,然后将它们相加。 原始的RoPE需要在query和key中融入相对位置信息。 如果对 采用 RoPE,那么当前生成 token 相关的 RoPE 矩阵会在 和 之间,并且矩阵乘法不遵循交换律,因此在推理时 就无法整合到 中。 基于这种解耦的 RoPE 策略,MLA 遵循的计算逻辑为: 其中: 和 分别表示计算解耦后的 queries 和 key 的矩阵 RoPE() 表示应用 RoPE 的操作; 表示拼接操作 推理时, # 由于 W^{UK} 只涉及 non rope 的部分所以维度中把 qk_rope_head_dim 去掉了。
复旦 NLP 实验室、华东师大、上海 AI Lab、海康威视联合提出 MHA2MLA 框架,通过部分 RoPE 保留(Partial-RoPE)和键值联合表示低秩近似(Low-rank Approximation 保留(Partial-RoPE)分离出 PE 相关表示(少量维度,如 1/8)和 PE 无关表示(大量维度),其中 PE 相关的键向量对齐 MLA。 部分 RoPE 保留(Partial-RoPE) 为了实现从标准的 MHA(多头注意力机制)到 MLA(多头潜在注意力机制)的迁移,作者提出了部分 RoPE 微调(partial-RoPE finetuning )策略,该策略通过从大量维度中移除 RoPE(旋转位置编码)并将其转换为 NoPE(无位置编码)来解决 MLA 和 RoPE 冲突的问题。 键值联合表示低秩近似 移除了大量维度的 RoPE 之后,MHA2MLA 就可以对值向量和 PE 无关的键向量进行低秩近似,从而大幅减少缓存空间。