Llmcad: Fast and scalable on-device large language model inference

devtools/2024/11/28 20:08:28/

题目:Llmcad: Fast and scalable on-device large language model inference 发表于2023.09

链接:https://arxiv.org/pdf/2309.04255

声称是第一篇speculative decoding+边缘设备的论文(不一定是绝对的第一篇),不开源,没有github地址

动机

生成性任务,在移动应用领域占据重要的地位。由于对隐私问题的敏感性,越来越多的需求是直接在移动设备上执行这些任务。目前,这些生成性任务的执行严重依赖于LLM。然而,这些设备内存容量十分有限。
在本研究中,引入了LLMCad,这是一个专为高效生成性NLP任务设计的设备端推理引擎

注意,它的目标模型也是在移动设备上的,只不过不放在内存中,只在验证时期从存储中加载到内存;小LLM是常驻内存的。

核心思想

LLMCad的核心思想围绕模型协作:一个紧凑的LLM驻留在内存中,负责生成最简单的令牌,而一个高精度的LLM则介入以验证这些令牌并纠正识别出的错误。LLMCad融合了三种新技术:

  • LLMCad不是以顺序方式生成候选令牌,而是使用较小的LLM构建一个token树。随后,较大的LLM可以同时验证所有这些路径。

  • 它采用自适应回退策略,每当较小的LLM生成错误令牌时,迅速启动验证过程。

  • 为了确保token生成的连续流动,LLMCad在验证过程中通过实施计算-IO管道来推测性地生成令牌。

论文基于以下观察:虽然较小的LLM不足以生成令人满意的端到端句子,但它们通常能够正确生成大多数简单的标记(例如,限定词、代词和标点符号)。目标LLM验证N个令牌可以在目标模型的一次推断中完成,因此比顺序生成N个令牌要快得多。

 策略

论文指出遇到的挑战以及解决策略:

  • 小LLM可能产生的一些次优token,实际上它认为的次优token是目标LLM的最优输出。这就需要在验证的过程中,也考虑到那些次优token,即使用tree attention

  • 需要确定何时启动验证过程,设备上的验证是耗时的,例如Jetson TX2上需要7.1秒。过早验证会导致检测不到错误,过晚验证会生成无用token,浪费了移动设备计算资源。先前的工作通常依赖于单个标记或标记序列长度,这可能无法准确地定位最佳验证时机。本文中token tree中比较累积不确定性、基于历史数据评估是否需要进行验证。

  • 目标LLM的验证会阻塞小LLM的推理。所以在验证过程中,继续让小LLM执行推理。同时为了保证小模型推理不影响验证,继续推理只在不影响大LLM内存占用的情况下运行。

下图是整个流程图:

设计

论文的一些设计细节:

  • 在小LLM生成token树的过程中,任何置信度高于阈值的token都会被生成一个分支(例如0.3)

  • 树累计置信度(tree cumulative-confidence),列的公式和字符看起来挺吓唬人,实际上就是同一个序列的每个token的置信度累乘

  • 关于如何并行地验证树,论文也是给了较长的介绍,但实际上应该是用了其他论文中出现的tree attention机制。详情可以看第一个提出tree attention机制的specInfer论文,在我的博客里也有这篇文章的解读。


http://www.ppmy.cn/devtools/137745.html

相关文章

部署自动清理任务解决ORA-00257: archiver error. Connect internal only, until freed

使用oracle数据库的时候,我们一般都会开启归档,确保数据库的日志连续和和数据安全。但随着数据库的运行,归档文件会越来越多,最终撑满磁盘空间,数据库无法继续归档,出现“ORA-00257: archiver error. Conne…

Web day02 Js Vue Ajax

目录 1.javascript: 1.js的引入方式: 2.js变量 & 数据类型 & 输出语句: 模板字符串: 3.函数 & 自定义对象: 4. json 字符串 & DOM操作: 5. js事件监听: 6.js的模块化导入或者导出&a…

C++虚函数面试题及参考答案

目录 什么是虚函数?它的作用是什么? 如何在 C++ 中声明一个虚函数?请举个例子说明。 虚函数如何实现多态?请给出简单示例。 解释什么是动态绑定(dynamic binding)与静态绑定(static binding)。 如果基类的函数是虚函数,派生类的对应函数是否需要再次声明为虚函数…

深入理解Go语言中的`sync.Pool`与常规内存分配

在Go语言的并发编程中,内存管理是一个不可忽视的话题。sync.Pool作为Go标准库中的一个特殊工具,提供了一种对象池化机制,以优化内存分配和垃圾回收(GC)。本文将深入探讨sync.Pool与常规内存分配的主要区别,…

uni-app 自定义平台如何进行 static 目录的条件编译

一. 自定义平台如何进行 static 目录的条件编译 关于如何自定平台,参考之前文章: uni-app 玩转条件编译:自定义平台的条件编译实战详解https://blog.csdn.net/qq_24956515/article/details/143951206 由于官方不支持创建自定义平台下的 st…

设计模式简介

设计模式的八个原则: 依赖倒置原则:高层次的代码(稳定)不应该依赖低层次的代码(变化),高层次的代码应该依赖于抽象。抽象的代码不应该依赖实现细节,实现细节应该依赖抽象。开放封闭…

C/C++基础知识复习(30)

1) 什么是 C 中的 Lambda 表达式?它的作用是什么? Lambda 表达式: 在 C 中,Lambda 表达式是一种可以定义匿名函数的机制,可以在代码中快速创建一个内联的函数对象,而不需要显式地定义一个函数。Lambda 表…

Vue2中 vuex 的使用

1.安装 vuex 安装vuex与vue-router类似,vuex是一个独立存在的插件,如果脚手架初始化没有选 vuex,就需要额外安装。 yarn add vuex3 或者 npm i vuex3 233 Vue2 Vue-Router3 Vuex3 344 Vue3 Vue-Router4 Vuex4 2. 新建 store/index.j…