llama.cpp Q 量化方式总结
llama.cpp Q 量化方式总结TheBloke 里有许多不同量化方式的模型,如下: 123456789CapybaraHermes-2.5-Mistral-7B-GGUF | - capybarahemers-2.5-mistral-7b.Q2_K.gguf | - capybarahemers-2.5-mistral-7b.Q3_K_L.gguf | - capybarahemers-2.5-mistral-7b.Q3_K_M.gguf | - capybarahemers-2.5-mistral-7b.Q3_K_S.gguf | - capybarahemers-2.5-mistral-7b.Q4_0.gguf | - capybarahemers-2.5-mistral-7b.Q4_K_M.gguf | - capybarahemers-2.5-mistral-7b.Q4_K_S.gguf | ... 它们都属于 llama.cpp 中 Q 量化定义的范围。llama.cpp 里的 Q 量化有两个格式:QX_Y 和 QX_K,第一种是对称量化和非对称...
MNN 自定义算子,以 AnyNet 为例
1. 介绍本文主要介绍如何在 MNN 中添加自定义算子,以 AnyNet 为例。AnyNet 添加了一个自定义算子,虽然可以用 pytorch 表达,并且导出 ONNX 和 MNN,但是节点过多,可视化工具无法很好的展示,因此本文尝试将 AnyNet 中的自定义算子添加到 MNN 中。 自定义 MNN 算子需要先将 pytorch 计算逻辑导出成 ONNX 节点,并且由 MNN 来解释。这需要首先将 pytorch 计算包装成 torch.autograd.Function,然后通过 torch.onnx.export 导出 ONNX 节点。然后通过 MNN 的 MNN::OpConverter 来解释 ONNX 节点。 2. AnyNet AnyNet 自定义了一个 SPNet 算子,并且使用 CUDA 实现了这个算子。SPN的结构,分为两种,分别是单路连接和三路连接: 实际上就是通过一个权重矩阵,上一个点迭代地给下一个点权重,对于单路连接和三路连接,有: $$\begin{align}h_{k,t} &= (1 - p_{k,t}) \cdot x_{k,...
Cosplay 视频转图片
Cosplay 视频转图片1. 介绍有很多时候 Cosplay 视频里的 Cosplayer 只有几个相同的画面,但是他们还是发出了一个短视频用于展示。我们想要把相同的画面剔除,对每个不同的画面保留一张图片。从信息论的角度来看,大部分 Cosplay 短视频的信息熵很低,只有几张图片是有意义的。这个项目就是为了尝试提取这些有意义的图片。 调研之后发现这是一个类似视频总结(Video Summarization)的问题。视频总结是一个很大的研究领域,有很多工作。这个项目只是一个简单的尝试,不会涉及到很多复杂的技术。 2. 方法受到 2401.04962v1 的启发,这个问题主要针对的是视频中的重复帧。我们可以通过计算每一帧的特征向量,然后通过聚类算法来找到相似的帧。这个项目使用了 K-means 算法来聚类。 2401.04962v1 的架构图如下: 这个工作将视频总结(Video summarization)工作分为了三个步骤: 使用 TransNetV2 对视频进行分割,得到单个短视频(shot),使用 CLIP 对每个短视频每一帧进行特征提取,得到每一个视频的特征描述...
powershell-autocomplete
Powershell 自动补全TODO: 编写 ADB 自动补全脚本,能够识别 ADB 设备并补全,类似 zsh 的补全体验 SSH 和 SCP 自动补全远程路径 从 Powershell Gallery 上使用 Install-Module 安装脚本之后,还需要使用 Import-Module 导入模块才能使用,如果希望自动加载,可以添加到 $PROFILE 中。
opencl-alloc-error
OpenCL Image 申请失败问题描述在使用 MNN 部署 ViT 的过程中,出现了这个报错: 1Alloc Image 3 x 49152 error, code:-40 解决方案这个问题是因为这个图像的尺寸超过了本设备 OpenCL 支持的最大尺寸,Adreno 630 的最大尺寸是 16384x16384,所以这个图像的尺寸 3x49152 超过了这个限制。这个尺寸出现的地方在 ViT 生成 QKV 的时候,这个尺寸是 768x2304,使用 RGBA 四通道 Image 时,reshape 之后的尺寸就是 3x49152。解决方案: 修改 MNN 的代码,将这个尺寸调整到小于 16384x16384。但是需要修改后续的计算代码 在导出模型时,不要将三个矩阵合并成一个矩阵进行计算,而是分开计算,这样就不会出现这个问题 Buffer 不会出错,可以使用 Buffer 代替 Image 进行计算,但是 MNN 没有自动 fallback 的功能,需要手动修改代码。设置 mode=72 (即 CPU 的线程参数),在 GPU 模式下它会被解释为使用 Buffer 格式还是...
Effective STL - 06 - Programming by STL
Programming by STL条款43:尽量用算法调用代替手写循环 如果你要做的是算法已经提供了的,或者非常接近于它提供的,调用泛型算法更清晰。 如果循环里要做的事非常简单,但调用算法时却需要使用绑定和适配器或者需要独立的仿函数类,你恐怕还是写循环比较好。 最后,如果你在循环里做的事相当长或相当复杂,天平再次倾向于算法。 条款44:尽量用成员函数代替同名的算法关联容器提供了count、find、lower_bound、upper_bound和equal_range,而list提供了remove、remove_if、unique、sort、merge和reverse。大多数情况下,你应该用成员函数代替算法。这样做有两个理由。首先,成员函数更快。其次,比起算法来,它们与容器结合得更好(尤其是关联容器)。那是因为同名的算法和成员函数通常并不是是一样的。 12345678910111213set<int> s;for (int i = 0; i < 1'000'000; i++) s.insert(i);// 1ms// 使用 rand 避...
Effective STL - 05 - Functor
Functor条款38:把仿函数类设计为用于值传递C 中的 qsort 使用的 函数指针 就是指针的拷贝,因此是一个默认的值传递。 因为函数对象以值传递和返回,你的任务就是确保当那么传递(也就是拷贝)时你的函数对象行为良好。这暗示了两个东西。第一,你的函数对象应该很小。否则它们的拷贝会很昂贵。第二,你的函数对象必须单态(也就是,非多态)——它们不能用虚函数。 不是所有的仿函数都是小的、单态的。函数对象比真的函数优越的的原因之一是仿函数可以包含你需要的所有状态。有些函数对象自然会很重,保持传这样的仿函数给STL算法和传它们的函数版本一样容易是很重要的。(像之前提到的算法中 Algorithms ,Points 类就使用了 PointsAverage 来保存对应的状态,我的实现使用了 lambda 和引用来保存求和的结果) 1234567891011121314151617181920212223242526272829/*使用 Bridge 模式*/template<typename T> // 用于修改的BPFCclass BPFCImpl: public una...
Effective STL - 04 - Algorithms
Algorithms条款30:确保目标区间足够大123456789101112131415vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7};cout << v << endl;// 对于使用区间的函数, 注意预先分配空间vector<int> v2;v2.reserve(v.size());transform(v.begin(), v.end(), back_inserter(v2), [] (int& a) { return a * 2;});cout << v2 << endl;v2.reserve(v.size() * 2);transform(v.begin(), v.end(), back_inserter(v2), bind(multiplies<int>(), placeholders::_1, 2));cout << v2 << endl; 注意:back_ins...
Effective STL - 03 - Iterator
Iterator条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator 123456graph A[iterator] --> B[const_iterator]A[iterator] --> C[reverse_iterator]C[reverse_iterator] --> D[const_reverse_iterator]C[reverse_iterator] -->|base| A[iterator]D[const_reverse_iterator] -->|base| B[const_iterator] iterator 能够比 const_iterator 有更好的泛化性能,特别是对于 insert 、erase 函数,他们只支持 iterator 而不支持 const_iterator。 我们已经有足够的理由相信应该尽量使用iterator取代const或者reverse类型的迭代器: insert和erase的一些版本要求iterator...
Effective STL - 02 - Vector and String
Vector and String条款13:尽量使用vector和string来代替动态分配的数组无论何时,你发现你自己准备动态分配一个数组(也就是,企图写“new T[…]”),你应该首先考虑使用一个vector或一个string。 坦白地说,我想到了一个(也是唯一一个)用vector或string代替动态分配数组会出现的问题,而且它只关系到string。很多string实现在后台使用了引用计数(参见条款15),一个消除了不必要的内存分配和字符拷贝的策略,而且在很多应用中可以提高性能。事实上,一般认为通过引用计数优化字符串很重要,所以C++标准委员会特别设法保证了那是一个合法的实现。 唉,一个程序员的优化就是其他人的抱怨,而且如果你在多线程环境中使用了引用计数的字符串,你可能发现避免分配和拷贝所节省下的时间都花费在后台并发控制上了。(细节请参考Sutter的文章《Optimizations That Aren’t (In a Multithreaded World)》[20]。)如果你在多线程环境中使用引用计数字符串,就应该注意线程安全性支持所带来的的性能下降问题。 条款14:...