- 博客(90)
- 收藏
- 关注
原创 TensorRT-LLM七日谈 Day5
在day2, 我们尝试了对于llama8B进行转换和推理,可惜最后因为OOM而失败,在day4,我们详细的过了一遍tinyllama的推理,值得注意的是,这两个模型的推理走的是不同的流程。llama8b需要显式的进行模型的转换,引擎的生成,而tinyllama则进行了隐式的执行。如果参考[1],也有明确的说明。目前模型的推理确实支持多种形式。
2024-10-15 20:57:20
393
原创 TensorRT-LLM七日谈 Day4
其中, 在model_loader()的调用中,实现了模型的加载和engine的构造。而在step_forward函数中,则实现了每次的step。在Day2 中,我们梳理了trt-llm对于TinyLLama的调用,在Day3,我们也熟悉了一下Trt-llm常规的三步流程。这里其实有个问题,在针对tiny-llama的部署中,其实没有显式的进行模型转换,那麽其推理接口中到底包含了什么?今天算是仔细过了一遍模型的生成,可以看到,其中包含了。其中,主要的时间都用于模型的构造了。最后完成了模型的推理。
2024-10-14 19:10:31
418
原创 TensorRT-LLM七日谈 Day3
今天主要是结合理论进一步熟悉TensorRT-LLM的内容从下面的分享可以看出,TensorRT-LLM是在TensorRT的基础上进行了进一步封装,提供拼batch,量化等推理加速实现方式。下面的图片更好的展示了TensorRT-LLM的流程,包含权重转换,构建Engine,以及推理,评估等内容。总结一下就是三步。不想看图的话,可以看看AI的总结,我放在附录中。下图也很好的展示的trt-llm推理的全流程。
2024-10-14 06:55:04
1079
原创 TensorRT-LLM七日谈 Day2
其实,目前为止,我们对于tensorrt-llm 这个库就已经有基本的认知了,它通过python作为接口,但是底层还是依赖tensorrt,cuda闭源的高性能实现,如果查看tensorrt-llm 的源码,还可以看到pybind的文件夹,里面包含了python和cpp的一些接口的转换和交互。进一步观察package的内容,可以看到,它由多个python文件组成,此外,在libs中也包含多个.so文件。昨天卡在了环境配置上,经过一天的等待,pip基本完成后,我们基于链接1,继续配置环境。
2024-10-13 22:42:54
524
原创 ARM assembly 13: Fibonacci
在assembly 12中,我们实现了GCD,它通过recursice的方式来实现计算。今天我们来讲Fibonacci,它的Recursive相比于GCD会更加复杂,所以值得进一步讲解。首先,我们还是看看Fibonacci的传统实现,那就是首先,我们展示一下code base。
2024-10-13 09:28:42
256
原创 TensorRT-LLM七日谈 Day1
Flag利用7天时间熟悉tensort-llm的代码架构,cublas的使用方式以及flash attention的调优。项目链接。
2024-10-11 21:58:23
397
原创 ARM assembly 12: GCD(最大公约数)计算
基于gcd.s,我们可以看到,gcd函数的两个参数可以分别被传入到r0,r1寄存器中,然后,我们可以基于此实现base case,也就是上述代码中 b == 0的情况。在完成了recursive中参数的计算后,我们需要把它们分别传入r0,r1(现在它们在r1和r4).接下来,利用bl操作执行迭代操作。我们尝试在汇编中实现上述逻辑,没有什么难点,需要注意SDIV用于实现 signed integer division。基于下面的gcd.s文件,我们尝试实现gcd函数。在nums.txt中,我们可以看到。
2024-10-10 08:35:58
388
原创 ARM assembly: lesson 11
在之前,我们提到,当函数的参数小于等于4个时,我们会把它存放于寄存器中,但是如果函数参数大于4个,我们就需要通过stack去进行参数的存储,这毫无疑问,将增加代码操作的复杂性,因为我们需要对于栈利用stack pointer进行控制。
2024-10-02 13:13:16
566
原创 ARM Assembly: Lesson 9 (for loops)
2. 构建一个判断条件,和两个分支,一个分支用于实现循环,一个分支用于处理终止情况,他们将指向两个label。为了将上述代码从C转换为汇编代码,我们需要。相关指令:branch, cmp。1. 利用一个寄存器存储i。
2024-10-01 09:54:53
408
原创 ARM Assembly: 第8课 branching
单个的B表示进入一个无条件的分支,而含条件的分支通常可以基于APSR 条件flag进行指令的执行。比如,基于condition flag z是否为1, 我们可以进行BEQ结果的判断。下面是各种条件分支的触发机制和与condition flag的关系。
2024-10-01 06:15:23
487
原创 ARM assembly 7
CMP指令通过计算 Rn - Operand2 来更新条件标志,但不存储结果。(即Rn大于等于Operand2),则设置为1。(换言之,有错位,反而设定为0)。CMP 通过隐式的减法操作来更新条件标志,但不存放结果。: 如果有符号溢出发生,则设置为1。: 如果结果为负,则设置为1。: 如果结果为零,则设置为1。
2024-09-29 19:41:39
258
原创 ARM Assembly 6: Shift 和 Rotate
将寄存器中的位向左移动,右边用零填充。左移相当于对二进制数进行乘以2的幂的操作。Rd: 结果存储的目标寄存器。Rn: 要进行位移的源寄存器。#shamt: 位移的位数(立即数)。S: 可选,若存在则更新条件标志。
2024-09-29 19:33:37
713
原创 ARM汇编:第四课(逻辑运算)
ADD 执行逻辑加运算,可以针对immediate 和 寄存器分别进行操作,但是基本逻辑一致,都是针对数字转换为二进制,然后进行与的操作。
2024-09-29 19:21:26
431
原创 ARM 汇编5 数据类型
在ARMv7-M处理器中,Byte对应8bits,Halfword对应16bits, Word对应32bits。而之所以two's complement 能够进行数字的表达,就是巧妙的利用了overflow的原理,如下图。关于负数,我们通常会基于two's complement的模式进行数字的表达。如下图,一个寄存器中包含8 nibbles,也就是32bits。而在展示中,我们通常会使用一位来表示4bits,也就是。2. 负数对应的表达是首先反转,1. 正数对应的表达是。所以,-18的表达就是。
2024-09-28 13:15:47
633
原创 ARM汇编3:
在下列代码中,变量var1,var2存储于内存中,我们不能通过mov去获取或者改变内存中的数值,下面介绍具体的方法。首先介绍如下语法知识。.data 的指令用于表示数据部分的开始,其中存储了已经初始化的数据。_start 表示代码entry point的位置。_start:.dataLDR可用于将内存中的数据(word)加载到寄存器。如上图指令,内存中的数据的拷贝,不能通过mov进行,需要通过LDR!具体介绍参考链接1。
2024-09-27 15:13:41
445
原创 ARM汇编语言: lesson 2(ADD, SUB, MUL, set CPSR)
在arm中,add, sub, mov都支持 sub 支持 register或者immediate的操作。而mul 只支持 寄存器的操作。
2024-09-27 07:27:38
540
原创 ARM汇编学习第一讲 MOV, Exit Syscall
准备硬件需求:一台可执行ARM 汇编的算力设备,可以是Raspberry Pi, 也可以是其他云端的虚拟机,也可以利用QEMU去仿真。资料查阅ARM架构的各种syscall信息。
2024-09-26 22:32:57
909
原创 数据结构与算法2 哈希表
关于哈希表,在python中,dict()和set()就是基于哈希表来实现对于字典的存储和管理,在CPP中,std ::unordered_map和 std::unordered_set 就是基于哈希表的实现, 而std::set 则是基于红黑树的实现。使用哈希表来存储和查找元素,能够在平均情况下实现 O(1) 的查找、插入和删除操作。
2024-09-11 16:01:29
332
1
原创 数据结构与算法1: 链表
对应的就是 A--> B 和 C--> D, 变为 A-->C --> B --> D . 为了实现这一操作, 我们每次需要对于两个链表的next node进行备份,然后再更改current node的相互关系,然后再去处理next node。在while循环中,我们每次需要判断cur_node, 但是更重要的是,在最后一次,cur_node必然为空,因此,最后需要返回的是prev_node.为了把两个链表进行拆分,我们需要将中间节点的next在备份之后,设定为0。然后,我们需要进行链表的反转。
2024-09-10 19:09:39
303
原创 理解dual softmax
基于来自图像A的[[1, n, 256])] 维度的特征描述子,以及来自图像B的[1, m, 256]的描述子,首先经过linear层的操作,将其转换为[1, n, 1] 和 [1, m, 1]的特征,对应下列函数中的z0和z1。然后,基于在两个维度的softmax和转秩操作,我们实现了dual softmax。之后,我们将z0,z1的数值与dual softmax的数值相结合,并将最后一行,和一列做特殊的填充,我们就实现了lightglue中稍微有点特殊的dual softmax的操作。
2024-09-10 18:35:54
466
原创 再谈全排列
画了树之后,你就知道,这个问题,是一个循环遍历的问题,但是再遍历的过程中,你需要基于过去的状态(哪些元素被存储了),改变你之后的行为。我们还需要考虑终止条件,然后,这是一个回溯的问题,那么你需要考虑的就是回溯之后需要怎样的处理。我们可以判断list的长度,如果list的长度和原数组一致,我们就可以保存。我们需要重置两个状态,一个是path中的元素,另一个是遍历到的元素的判断。每次做全排列的题目,我都要孕育好一阵子,到底怎么去思考这个问题呢?首先,我觉得最好的方式就是画个树。1. 如果保存过去的状态。
2024-09-05 17:06:49
385
原创 CPP八股文-模板类.内存管理,指针
无论是类模板还是函数模板,都是一个蓝图,本身不是一个类或函数,编译器用模板产生指定的类或函数的特定类型版本。产生模板的特定类型实例的过程称为模板的实例化。所以一般将模板类放在头文件中,在编译时,基于使用的具体对象的类别,生成对应的对象。继承语言特性带来的多态性,是程序运行时体现出来的,称为运行时多态性。泛型编程的多态性,是在编译阶段体现的,称为编译时多态性。
2024-09-02 23:21:31
259
原创 八股文整理C++
调用 `basePtr->show()` 时,虽然 `basePtr` 类型为 `Base*`,但由于动态绑定,程序在运行时会调用 `Derived` 类的 `show()` 方法,而不是 `Base` 类的 `show()` 方法。在这个例子中,`Base` 类是一个抽象类,因为它包含一个纯虚函数 `show()`。在这个例子中,尽管 `b` 是一个指向 `Base` 类型的指针,但由于 `show()` 是虚函数,所以在运行时,它调用了 `Derived` 类的 `show()` 函数。
2024-09-01 10:15:52
1405
原创 Swin-Transformer论文阅读
在CNN对于图像分类,目标检测等问题的探索中,大家已经发现,母舰检测,语义分割这类任务,相比于图像分类对于网络backbone有着不一样的需求。而基于vit对于图像分类问题的探索,接下来,大家可以依葫芦画瓢,尝试解决更有挑战的问题了。关于目标检测,语义分割这类任务,通常需要网络具有分层提取不同颗粒度的特征,并且,网络的是输入可能是更高分辨率的图像,输出也是更精细的特征,比如语义分割的mask。
2024-08-20 08:49:58
1034
1
原创 VIT论文阅读: A Image is Worth 16x16 Words
在2024年,大家都知道了transformer的故事,但是在4年前, CNN和Transformer谁才是CV的未来,还没有那么确定。在简介部分,作者提到了一个令人失望的事实,在基于imagenet的实验中发现,transformer的表现差于同尺寸的ResNet。作者把原因归结到bias translation equivariance and locality,这些CNN具有,但是transformer不具有的特性上。如下图【1】
2024-08-18 10:47:46
655
1
原创 AOT & JIT介绍
可以看到,在jit模式下,第一次运行涉及到图的构建,会需要更长的时间,但是在完成warm up之后,速度会比第一次有明显提升。因为,在运行的时候,我们只需要编译一部分的程序。此外,JIT还会基于输入的大小,类型进行图的优化,还会将此前见到的一些输入类型放入缓存,并重新利用。此外,JIT还具有一高效特性,dynamic tracing, 基于数据流,可以生成计算图,也就是DAG(directed acyclic graph),基于该图,我们可以进行进一步的优化,某些情况下,该优化效果甚至强于AOT。
2024-08-17 18:15:51
691
原创 ONNX导出问题解析
在torch模型转换为onnx的过程中,使用的是torch.jit,ScrptModule,而不是torch.nn.Module,关于这两者的区别,有不少更好的视频介绍,简单理解为前者用于提供模型静态图推理,强调性能,后者强调“简洁,美丽”,是一种不关注性能的动态图。今天在进行onnx的模型导出时,遇到了一个问题,如标题,就是“torch.roll"这个算子在从pytorch到onnx的转换过程中会失效。对应的解决方法是,把pytorch的版本升级,原先的版本是1.8,后来升级到了1.10。
2024-08-17 08:06:56
410
原创 yield and generator in python
首先,假设大家都对于pytyhon的List comprehension的使用有了一定经验(它可以用于list,set,和dict哦)不熟悉的参考介绍: Comprehending Python’s Comprehensions – dbader.orggenerator是哦嗯一种返回lazy iterator的特殊类型函数。list comprehensions return full lists, while generator expressions return generators.如下面代码,分
2024-08-03 15:21:50
762
原创 理解slot mapping
这表示,基于block size为8的kv cache,sequence length为16时,slot mapping的分配. 其中,seq将占据两个block,每个slot mapping中sequnce对应的block index就是[0] *8, [1] *8, 而在block中的index对因的就是[0,1,2,3,4,5,6,7,8]..为了理解它,尝试参考源代码构造一个简单的slot mapping。今天尝试理解slot mapping的作用, 参考。
2024-07-26 13:32:00
567
原创 VLLM代码解读 | VLLM Hack 3
这里,hidden_states尺寸为 [26,768], logits的维度为[4, 50272], output对应的数据类型为vllm.sequence.SamplerOutput. 这里4对应的就是输入数量,26对应的是输入的总token数。至此,我们完成了一次迭代,得到了请求的输出,如下面的代码,但是,之前讨论的流程中,我们似乎没有找到区分decode和prefill流程的模块,必然是忽视了一些重要细节。看到这里,我已经失去耐心了,meta几个文件的代码怎么被搞的这么复杂。
2024-07-25 08:51:14
1067
原创 VLLM代码解读 | VLLM Hack 2
这个对象用于保管基于同一prompt生成的sequences,可以想象,当进行beam search的时候,我们需要保证sequence的平行宇宙,对应确实需要更好的数据结构去维护它。需要注意的是,scheduler中维护了三个队列,分别为waiting,running,swapped。到目前为止,我们基本完成了输入的封装,让它成为了一个sequencegroup,包括输入对应的token,一个ID,并且交给scheduler调度。因为llmdemo中默认为4的输入,下列的操作我们要进行4次。
2024-07-25 07:50:23
302
原创 VLLM代码解读 | VLLM Hack 1
好,我要去上班了,今天,我们从VLLM的example调用,见证了llm如何启动offline inference,然后基于输入的string一步步封装,目前为止,我们看到它被封装成了sequence这个对象,并且已经考虑到了block size这些和显存占用直接相关的参数,接下来会发生什么?接下来调用_add_processed_request函数,这里使用了一个重要信息,block_size:16,基于它和input信息,我们构建sequence对象。
2024-07-24 08:54:31
581
原创 Llama中模块参数大小
对于一个batch的数据来说哦,因为llama2 7B 包含32个transformer,所以,当使用FP32表达时, 对应一个batch的kv cache的大小为128 * 32 * 128 *2 * 32 * 4byte= 0.5GB.llama2设定 local_kv_heads为32,head_dim为128。所以,kv cache的尺寸为 [1, 512,32, 128] * 2。* 当batch 的最大长度增大时, Kv cache线性增长。* 当batch变大时,kv cache线性增长。
2024-07-21 22:37:44
757
原创 llama2阅读: logits是什么?
在llama2中,当模型进行推理后,得到的是一个[1,n, 32000]的输出,然后基于第n个向量[1,32000], 可以进行sample_top_p,或者argmax的处理,来获得下一个token对应的index,只需要利用tokenizer的解码就可以生成token了。通过这种方式,我们可以实现对对于token的缓存和更新。而在llama2的代码中,同样有logits的使用,那么针对llama2,logits的作用是什么呢?
2024-07-06 06:48:36
635
原创 Lex Fridman Podcast with Andrej Karpathy
但是更令我感到认同的是,他对于公司治理也有自己的观点,他认为start up就需要 聪明的人有big hammer。我不太喜欢Lex Fridman的声音,总觉得那让人昏昏欲睡, 但无奈他采访的人都太大牌了,只能去听。但是听着听着,就会觉得有深度的采访这些人,似乎也只有他这种由研究员背景的人能干, 另,他提的问题确实具有很好的引导效果,有时候非常虚,有时候又直接具体到问你用什么IDE写代码。当Lex问道,你认为LLM是一切的开始,还是中途,还是结束时,他坚定的回答,是开始。
2024-07-05 22:38:36
399
原创 关于目标检测的bbox
box的前两个数字可能表达 [x_min, y_min],或者[x_center, y_center], 后两个数字可能表达[x_max,y_max]或者[w, h]. 不同的数据集或者检测模型有不同的定义,比如coco中, box 定义如下。关于目标检测的bbox,最让人抓狂的,就是你永远不能对于box的定义掉以轻心, 虽然box就是一个正方形,四个数字,但是如果没有正确理解其对应的含义,会对于mAP的计算等任务产生灾难性的影响。所以,当你的目标检测可视化不正确的时候,也许可能只是box的使用有问题。
2024-07-02 21:39:02
553
原创 基于nsight_compute进行kernel性能分析
当利用nsight进行性能分析时,当涉及到内核级别的性能分析时,nvidia提供了系统级别(nsight system),和内核级别的性能分析工具(nsight compute)。其中,内核级别的性能分析,可以检查kernel实现的性能好坏及bottleneck。本次主要对比的是cublas和基于naive cuda实现的kernel性能对比:cublas的实现可以理解为最优解,而naive cuda的kernel没有进行,global memory。共享内存或者寄存器相关的优化。
2024-06-23 11:30:44
1188
原创 RAG_Example
1. 文本转换过程中,PDF的信息可能会丢失和损坏。比如对于一个只包含很多小标题的文档,我怀疑是否能够获得足够多的有效信息。此外,一些文档中的信息,是通过图文结合的方式,这种信息是否能有效获取呢?2. LLM基座模型的选择比较重要,目前来看,模型可以理解中文,但是不能说中文,这是一个问题,想到的解决方案就是替代基座模型。3. 目前由于使用不够充分,无法给出结论,但是目前感觉每个环节都可能会出问题。主要流程包括下面几个模块,每一个模块都有很多选择,而不是唯一解。但这里可以感受到潜在的几个问题。
2024-06-14 07:50:39
216
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人