InternLM2/LM2.5/ViT/VL1.5/VL2.0笔记: 核心点解析

article/2025/6/7 13:31:46

00 前言

        本文主要是记录一下关于多模态大模型InternLM/InternVL系列的一些要点的理解。还是那句话,好记性,不如烂笔头。本文当成个人笔记用,行文风格和先前写的LLaVA系列一致。本文的重点是讲解多模态模型InternVL 1.5,但是InternVL 1.5选择了InternLM2作为LLM底座,以及使用InternViT-6B作为视觉理解模型。因此,本文也先从InternLM2和InternViT开始讲起。InternLM2和InternViT以简单说明为主。推荐先阅读,DefTruth:[LLaVA系列] CLIP/LLaVA/LLaVA1.5/VILA笔记(https://zhuanlan.zhihu.com/p/683137074)。

01 InternLM2 简析

  • InternLM2 模型结构: LLaMA + GQA

                                                                    InternLM2模型结构

        InternLM2采用了LLaMA的模型结构,并且和LLaMA一样,使用了GQA。LLaMA大家都比较熟悉了,就不再重复说明了。不过比较有意思的是,为了提高Tensor Parallel的效率,InternLM2对Wqkv的权重进行了交织重排,下一小节将会继续介绍这个技术。

Interleaving Wq, Wk, Wv

                                                        InternLM2权重交织

        InternLM2对比InternLM一个比较大的改变就是,对Wqkv的堆叠权重矩阵进行了交织重排,根据论文的说明,这个操作降低了Tensor Parallel下权重矩阵分发的复杂度。InternLM采用和LLaMA完全一样的做法,Wqkv是由Wq, Wk和Wv顺序stack在一起构成,这种做法,在使用Tensor Parallel时,需要执行更多的操作(比如各种slice、cat)才能将权重矩阵正确地切分到不同的GPU上,导致这块会产生一个非常碎片化的子图,对backward/forward效率都有一些影响。而InternLM2的Wqkv矩阵不是直接顺序stack的,而是对三个矩阵进行交织重排(上边这个图表达地应该很清晰了),使用Tensor Parallel的时候,只需要一个split操作就能完成矩阵切分,减少了大量冗余的操作。这个交织重排操作,大概能提高5%的训练效率 

        不过,这个权重交织的操作,虽然可以提升训练效率,但是对下游的部署任务来说,就不是那么友好了。虽然InternLM2是LLaMA结构,但是Wqkv使用权重交织后,就没办法使用常用的部署方式了。因此,目前看到社区对InternLM2的部署支持也分为两种方式,分别是(1)LMDeploy原生支持,LMDeploy无缝衔接InternLM2系列的部署,开箱即用,性能也不错;(2)de-Interleaving Wq, Wk, Wv -> LLaMA,即先对权重解交织,还原成标准的LLaMA结构和参数保存格式,然后就可以开心地使用现有的众多框架进行部署了。InternLM官方也提供了转换工具,非常nice,具体请参考:

        InternLM Convert Toolshttps://github.com/InternLM/InternLM/tree/main/tools

        其中解交织部分的代码如下。这个gs表示就是上图中有多少个query head和kv的权重交织在一起,num_key_value_groups就是query head的数量,这些query head对应相同的KV,2是指k和v各占一份。torch.split在dim=1按照 [num_key_value_groups, 1, 1] 进行切分,这是由于使用了GQA,多个query head对应一组KV head,在split的时候要符合GQA的要求。split得到Wq,Wk,Wv权重矩阵后,在reshape回原来的二维矩阵的维度。其他剩余的逻辑主要就是权重name的一对一匹配了,这个很好理解。关于rearrange用法,推荐阅读(非常清晰):科技猛兽:PyTorch 70.einops:优雅地操作张量维度(https://zhuanlan.zhihu.com/p/342675997)

                                                                        权重解交织逻辑

                                                         num_key_value_groups计算逻辑

  • TensorRT-LLM中的InternLM2权重解交织

        另外,目前在TensorRT-LLM中,支持直接使用InternLM2原生模型进行checkpoint转换、build engine和推理,我们可以从convert_checkpoint.py中的逻辑可以看到,其中执行了权重解交织操作,然后使用TensorRT-LLM的API进行权重的赋值以及组网操作,并且调用了tensorrt_llm.models.llama中的convert组件,来对权重进行正确的转换。不过,在目前的实现中,还不支持FP8/SQ量化,只支持Weight Only。因此,如果需要走FP8量化部署的方案,还是建议走”de-Interleaving Wq, Wk, Wv -> LLaMA“的方案。TensorRT-LLM中示例见:https://github.com/NVIDIA/TensorRT-LLM/tree/main/examples/internlm2

                                        TensorRT-LLM InternLM2 权重解交织

  • LMDeploy中的InternLM2的权重解交织

        另外,我们再回到LMDeploy的源码看下交织后的权重是如何妥善处理,并利用TurboMind后端推理的。具体代码如下。从代码中看到,LMDeploy的实现,实际上也是先将权重进行解交织,并且对权重按照name一对一匹配,接着使用LLaMa结构进行转换,InternLM2Reader继承的是LlamaReader。详细代码见:

        https://github.com/InternLM/lmdeploy/blob/main/lmdeploy/turbomind/deploy/source_model/internlm2.py

                                                 LMDeploy中的权重解交织

  • vLLM中的InternLM2权重解交织

        作为LLM推理主流框架之一的vLLM,自然也是支持InternLM2的部署,大致瞄了一眼其中的实现,对于权重解交织的处理和TensorRT-LLM以及LMDeploy是完全一致的。(PS:这么说,权重交织这个事儿对于推理来说是不是有点多余了,实际部署的时候全都是得先解交织一遍...),代码见:

https://github.com/vllm-project/vllm/blob/main/vllm/model_executor/models/internlm2.py#L313

                                                                InternLM2权重交织

02 InternLM2.5简析

  • InternLM2.5最新进展

        2024年7月3日,InternLM团队发布了InternLM2.5,模型结构和InternLM2一样,效果更好。大概看了下,这次主要是更新了7B系列的Chat模型。其中InternLM2.5-7B-Chat-1M模型支持百万长度的上下文窗口。这次发布的主要核心点有三个:(1)卓越的模型推理能力,在数学推理的任务上达到了SOTA,超过了同等规模参数量的其他模型,如LLaMA3-8B和Gemma-9B;(2)支持百万长度上下文长度的推理,并且可以通过LMDeploy快速部署,开箱即用(PS: 他们家训推一整套无缝衔接做的真的太棒了!赞!LMDeploy性能和用户体验都不错。);(3)增加了更多的应用工具的支持,比如快速对大量的网页信息进行聚合,后续也将会整和到Agent工具中。

                                                                 InternLM2.5

  • InternLM2.5 Benchmark

        可以看到,InternLM2.5 7B Chat模型在多项任务上都达到了同等参数规模模型的SOTA水平,并且在Math任务上,比LLaMA3-8B-Instruct和Gemma2-9B-IT要高出一大截啊,说实话,有点被震惊到了。

                                                 InternLM2.5 Benchmark

 03 InternViT简析

  • InternViT模型结构解析

图片

                                                                      InternViT-6B

        InternViT-6B采用的就是经典的ViT模型结构,作为InternVL的视觉模块进行使用,不单独使用。ViT参考文献:arxiv.org/abs/2010.1192(https://arxiv.org/abs/2010.11929)9;ViT经典模型结构如下:

                                                              ViT经典模型结构       

         从实现的代码上看,InternViT主要由VisionEmbeddings和VisionEncoder两个大模块组成,VisionEmbeddings负责将图像编码成Embedding,并且position embedding采用了可学习的方式,forward时,会将图像patch embedding和position embedding相加,得到ViT的输入,然后送入VisionEncoder进行推理。VisionEncoder中包含多层标准的Transformer层,也就是InternVisionEncoderLayer。

更详细的实现,可以参考官方的代码:https://github.com/OpenGVLab/InternVL/blob/v2.0.0/internvl_chat/internvl/model/internvl_chat/modeling_intern_vit.py

                                                      InternViT模型源码

                                                        position embedding

04 InternVL1.5简析

  • InternVL1.5整体结构

                                                       InternVL1.5整体结构

        InternVL 1.5整体结构包括3个部分:ViT、MLP Projector和LLM底座。ViT模型选择的是一个6B的模型,作为强视觉特征提取器,参数规模由以前的几百M,跃升到和大模型一个级别;MLP Projector则是负责将视觉特征和语言模型的特征空间进行对齐,InternLM2-Chat-20B的embedding维度是6144,MLP Projector会将视觉特征转换到相同的维度;LLM底座选择的是自家的InternLM2-Chat-20B。InternVL 1.5的总体参数量是26B。并且,在整体框架中我们还看到另外两个技术手段,分别是Pixel Shuffle和Dynamic High Resolution;Pixel Shuffle主要是用来重排ViT提取到的pixel feature,目的是减少visual token的数量并保持特征信息不丢失,而Dynamic High Resolution,即动态高分辨率,则是为了让ViT模型能够尽可能获取到更细节的图像信息,提高视觉特征的表达能力。接下来,本文会对这个两个技术做详细的解析。

  • Pixel Shuffle: 减少visual token数量

        Pixel Shuffle在超分任务中是一个常见的操作,PyTorch中有官方实现,即nn.PixelShuffle(upscale_factor) 该类的作用就是将一个tensor中的元素值进行重排列,假设tensor维度为[B, C, H, W], PixelShuffle操作不仅可以改变tensor的通道数,也会改变特征图的大小,先看官方文档:

                                                                     nn.PixelShuffle

        即把维度(B, C x r x r, H,w) reshape成 (B, C, H x r,w x r), 给出的例子,假设upscale因子是3,输入通道是9,则输出通道是9/3/3=1, 输出大小为输入大小乘以upscale。nn.PixelShuffle的解释,参考自:像阳光 像春天:torch.nn.PixelShuffle(upscale_factor)函数详解(https://zhuanlan.zhihu.com/p/562932795)。如果upscale_factor值大于1,则相当于H,W变大,channel数变少,是一个上采样操作。InternVL 1.5中的pixel shuffle与torch中略有不同,但原理是一样的,InternVL 1.5中是自己写了一个pixel shuffle的操作,他的这个操作刚好相反,是一个下采样操作,实际使用的scale_factor为0.5,其实就相当于把更多的像素保存在channel维度上,所以pixel shuffle后,H, W变小了,channel数变多了。对于scale_factor,比如0.5,pixel shuffle将输入[N, W, H, C]转换成shape为[N, H x scale, W x scale, C//(scale^2)]的Tensor。 

                                                                        pixel shuffle 

        我们来看下InternVL-Chat-V1.5中的实际调用链路,具体逻辑如下图,其中pixel_values是指组batch后原始的图像输入,比如shape为[5,3,448,448]。InternVL 1.5中默认select_layer为-1,即提取最后一层的hidden_state作为feature map。提取到feature map之后就会调用pixel shuffle函数对feature map进行处理。 

                                                pixel shuffle at extract_feature 

通过打印日志,我们可以清晰地看到visual embedding在extract_feature过程中shape变化:

[INFO]: extract_feature pixel_values: torch.Size([5, 3, 448, 448])[INFO]: extract_feature vit_embeds: torch.Size([5, 1025, 3200])[INFO]: extract_feature vit_embeds[:, 1:, :]: torch.Size([5, 1024, 3200])[INFO]: extract_feature vit_embeds after reshape: torch.Size([5, 32, 32, 3200])[INFO]: extract_feature vit_embeds after pixel_shuffle: torch.Size([5, 16, 16, 12800]), downsample_ratio: 0.5[INFO]: extract_feature vit_embeds before mlp1: torch.Size([5, 256, 12800])[INFO]: extract_feature vit_embeds after mlp1: torch.Size([5, 256, 6144])[INFO]: input_embeds: torch.Size([1, 2596, 6144])[INFO]: input_embeds [B*N, C]: torch.Size([2596, 6144]) 

        可以看到,这个示例中,pixel shuffle的ratio=r=downsample_ratio=0.5。并且pixel shuffle是在提取的vit emb上调用的,而不是在原始图像上,具体可以看上图源码的逻辑,举个实际的例子,[5, 3, 448, 448]的pixel_values经过InternViT-6B后,得到[5, 1024, 3200]大小的feature map,按照hxw的空间布局reshape后为[5, 32, 32, 3200],其中32x32就是原始的visual token数,3200就是特征channel数。接着对[5, 32, 32, 3200]的feature map进行pixel shuffle处理,r=0.5,变换得到[5, 16, 16, 12800]。我们可以看到,pixel shuffle之后visual token数量变成了原来的1/4,即16x16=256。最后,再将[5, 16, 16, 12800]reshape为[5,256,12800],并经过MLP1,得到[5, 256, 6144]。这个6144就是LLM语言模型InternLM2-20B的hidden_size,见config.json中的配置:

                                     InternLM2-20B的hidden_size 

        可见,对于一个448x448的image来说,经过ViT + pixel shuffle后,visual token数由原来的32x32下降到了16x16,token数下降到了原来的1/4,既保留了原始的feature信息,又达到了减少上下文长度的效果。

  • Dynamic High Resolution: 动态高分辨率

        Dynamic High Resolution具体的做法为:对于输入的图片,首先resize成448的倍数,比如InternVL 1.5中,设置的比例为2:3,也就是resize成(H=448x2=896, W=448x3=1344),然后按照预定义的尺寸比例从图片上crop对应的区域。首先,将图片划分成2x3的块,Aspect Ratio=1:1就是表示取最左上角的块,而1:2则是取第一行中间的块,以此类推其他的Ratio代表的含义。并且,为了能够捕获全局的信息,还将整图resize成448x448,作为Thumbnail和其他crop出来的图像stack到一起作为输入。

                                                Dynamic High Resolution 

        具体到InternVL 1.5的预处理代码,我们可以看到,代码中首先会根据max_num生成一系列备选的ratio,并且通过set去重,然后是调用find_closet_aspect_ratio找到和aspect_ratio最匹配的target_aspect_ratio,这是为了保持一致的宽高比,避免不合理的resize导致图片失真。比如输入是800x1300的图片,会找到最优的ratio为2:3,然后会根据这个ratio以及image_size=448,将输入图片resize为448的倍数,即896x1344。所有需要crop的blocks数量等于2x3=6,需要留意的是,由于在获取target_ratios的时候,已经限制了 i*j <= max_num,因此,blocks的值总是满足max_num的限制的。 

# calculate the existing image aspect ratio
    target_ratios=set(
        (i,j)
        forninrange(min_num,max_num+1)
            foriinrange(1,n+1)
                forjinrange(1,n+1)
                    ifi*j<=max_numandi*j>=min_num
    )

        接下来,就是通过一个for循环来计算第i个block对应的图片块范围,然后crop对应的区域获得的当前的图像块,图像块之间不存在跳变和跨越。我们推测,如果max_num值越小,那么对应的target_aspect_ratio的值也会越小,输入图像会在resize到一个相对小的尺寸,然后crop对应的blocks(但是这个尺寸也是比原图要大的),也就是,能够catch到的图像细节就越少;反之,输入图像会在resize到一个更大的尺寸,然后crop对应的blocks,能够catch到的图像细节就越多。在实际训练的时候,由于训练资源的限制,InternVL 1.5选择了最大的max_num为12,加上thumbnail就是13个块,对应到visual token数就是256x13=3328,而在推理时则没有这个限制,最大max_num可以到40,也就是visual token数可以到256x41=10496。

                                                        dynamic preprocess源码 

  • 模型训练、Prompt拼接和实验结果

模型训练:InternVL 1.5训练分为2个阶段。阶段一:对MLP Projector和InternViT-6B模型做预训练,LLM底座权重冻结,这个阶段主要是针对视觉特征提取器进行优化;阶段二:InternViT-6B + MLP Projector + InternLM2-20B总共26B的参数全部参与训练,上下文长度设置为4096,并且采用和LLaVA一样的prompt格式。

Prompt拼接:Prompt拼接逻辑也比较简单,具体操作是,将img_tokens放在用户prompt的前边,并根据对话模版进行填充。以下代码片段来自InternVL 1.5 HuggingFace仓库源码:

image_tokens =IMG_START_TOKEN+IMG_CONTEXT_TOKEN*self.num_image_token*image_bs+IMG_END_TOKENquestion=image_tokens+'\n'+questiontemplate.append_message(template.roles[0],question)template.append_message(template.roles[1],None)query=template.get_prompt()

        img_token_id是通过一个fake的特殊token先进行填充的,等Vision Model提取到真实的特征后,会进行替换:

                                         填充真实的img feature

        不过需要注意的是,实际上img_token_id并不是在整个prompt的最前方的,因为还会根据chat template进行填充,真正输入LLM模型的input_ids是填充后的prompt分词的ids,实际的prompt长这样:

 <|im_start|>system
You are an AI assistant whose name is InternLM (书生·浦语).<|im_end|><|im_start|>user
<img><IMG_CONTEXT><IMG_CONTEXT>...<IMG_CONTEXT></img>
describe this image<|im_end|><|im_start|>assistant

实验结果:剩下就是各种高质量的数据集的整理和说明了,模型结构都是主流的,训练数据的质量很大程度影响模型的效果,具体的细节请看InternVL 1.5的论文,本文不再单独说明。最后,放一下InternVL 1.5的benchmark:

                                                        InternVL 1.5 Benchmark 

可以看到,InternVL 1.5在多个任务和评估标准下都达到了SOTA的水平。

  • LMDeploy部署及性能瓶颈分析

        目前,针对InternVL系列的部署方案,最丝滑的,还是推荐使用LMDeploy。之前还有部署之后输出效果随机性明显的问题(greedy采样下),后来都修复了,见:https://github.com/InternLM/lmdeploy/pull/1741。不过,测试下来,发现,在BS变大后,性能瓶颈或许已经不在LLM模型,而是在没有经过优化的InternViT-6B的视觉模型上了。具体见issue:https://github.com/InternLM/lmdeploy/issues/1869。

                                                LMDeploy VL 视觉模型推理

        我们可以看到,InternViT-6B视觉模型,使用了HF+accelerate推理,虽然权重平均分配到两张卡上,但是推理是逐层串行的,没有通过Tensor Parallel利用双卡的算力。随着视觉模块参数量的不断增大,比如未来VLM是否会出现搭配10B、20B以上参数量级的视觉模块?如果出现,那么对视觉模块+LLM基座结合起来做深度的性能优化,应该是不可避免的。

                                                         InternVL 部署性能分析

05 InternVL2.0简析

  • InternVL2.0最新进展

        2024年7月份,InternVL团队发布了InternVL 2.0,效果比InternVL 1.5更好。InternVL 2.0整体的网络结构和InternVL 1.5是一样的,Pixel Shuffle和Dynamic High Resolution的技术从InternVL 1.5继承了下来。但是InternVL 2.0进一步支持了医疗图像和视频作为输入,在功能上是比较大的变化。这次没有发布论文,不过有blog进行的说明,具体见:https://internvl.github.io/blog/2024-07-02-InternVL-2.0/

                                                        InternVL2 整体结构

        相对于InternVL 1.5,这次更新的InternVL 2.0主要的创新有:(1)提出了渐进式对齐的训练策略:实现了与LLM原生对齐的视觉基座模型,渐进式训练策略使得模型从小到大,数据从粗到细训练。InternVL2.0以相对较低的成本完成了大模型的训练。这种方法在有限的资源下表现出了出色的性能。(2)多模态输入:通过一组统一的参数,InternVL2.0模型支持多种输入模态,包括文本、图像、视频和医疗数据。(3)多任务输出:基于VisionLLMv2,InternVL2.0模型支持各种输出格式,例如图像、边界框和掩模,具有广泛的多功能性。并且,通过将 MLLM 与多个下游任务解码器连接,InternVL2 可以推广到数百个视觉语言任务,同时实现与专家模型相当的性能。

                                                         InternVL 2.0创新点

  • InternVL2.0 Benchmark

        InternVL 2.0在多项测试标准中均达到了SOTA,并且,这次还发布了一个108B参数量级的模型,可以说是把开源多模态大模型参数量的天花板又往上提了一提。真是力大飞砖啊,不得不感叹,有钱真好~

                                                 InternVL 2.0 Benchmark

06 总结

        本文梳理了InternLM/InternVL系列的模型结构,详细讲解了InternLM2/InternVL1.5的算法原理,包括权重交织、Pixel Shuffle和Dynamic High Resolution等关键技术的细节理解。最后,LLM推理部署各方向新进展,推荐我整理的Awesome-LLM-Inference,传送门:https://github.com/xlite-dev/Awesome-LLM-Inference


http://www.hkcw.cn/article/TuLaDmHEKk.shtml

相关文章

帝可得 - 设备管理

一. 需求说明 设备管理主要涉及到三个功能模块&#xff0c;业务流程如下&#xff1a; 新增设备类型: 允许管理员定义新的售货机型号&#xff0c;包括其规格和容量。 新增设备: 在新的设备类型定义后&#xff0c;系统应允许添加新的售货机实例&#xff0c;并将它们分配到特定的…

建设指南 | Cloud Apps + AI Apps端到端智能应用开发平台

在“云AI”作为基础设施的时代&#xff0c;研发、运维、信息化等部门&#xff0c;通常会面临的棘手问题都有哪些&#xff1a; 算力资源难以统一调度和管理&#xff1b;AI算法研发环境搭建复杂&#xff1b;不同模型部署方式繁杂&#xff0c;统一监控难&#xff1b;AI应用开发效…

【灵动Mini-F5265-OB】vscode+gcc工程创建、下载、调试

【前言】 【灵动Mini-F5265-OB】在官方的例程中提供了mdk、IAR的开发环境&#xff0c;使用起来非常方便。有位大佬也提供了一个gcc的示例&#xff0c;但是我使用vscode的keil插件进行工程创建&#xff0c;但是提示pack是对不上的。所以我决定重新创建我的vscode来创建开发环境。…

【AI论文】VF-Eval:评估多模态大型语言模型(MLLM)在生成人工智能生成内容(AIGC)视频反馈方面的能力

摘要&#xff1a;多模态大型语言模型&#xff08;MLLMs&#xff09;最近在视频问答领域得到了广泛研究。然而&#xff0c;现有的大多数评估都侧重于自然视频&#xff0c;而忽视了合成视频&#xff0c;例如人工智能生成的内容&#xff08;AIGC&#xff09;。与此同时&#xff0c…

Docker 镜像(或 Docker 容器)中查找文件命令

在 Docker 镜像&#xff08;或 Docker 容器&#xff09;中运行如下两个命令时&#xff1a; cd / find . -name generate.py它们的含义如下&#xff0c;我们来一行一行详细拆解&#xff0c;并结合例子讲解&#xff1a; ✅ 第一行&#xff1a;cd / ✅ 含义 cd 是“change dire…

DiskGenius专业版v6.0.1.1645:分区管理、数据恢复、备份还原,一应俱全!

各位小伙伴&#xff0c;大家好&#xff01;今天阿灿给大家带来一款超好用的分区工具&#xff0c;DiskGenius专业版。这款工具堪称电脑管理界的“瑞士军刀”&#xff0c;功能强大&#xff0c;现在出了新版本v6.0.1.1645&#xff0c;简繁中文单文件便携版&#xff0c;使用超方便。…

‌CDGP|数据治理的低效性:企业AI落地的另一大挑战

在数字化转型的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动企业创新发展的重要力量。然而&#xff0c;尽管AI技术具有巨大的潜力和优势&#xff0c;但许多企业在尝试落地AI项目时却面临着重重挑战。其中&#xff0c;数据治理的低效性尤为突出&#xff0c;…

linux学习第19、20天(父子进程)

ps ajx -->查看pid&#xff0c;ppid&#xff0c;gid&#xff0c;sid 父子进程 父子进程相同&#xff1a; 刚fork后&#xff0c;data段、text段、堆&#xff0c;栈、环境变量、全局变量、进程工作目录位置、信号处理方式 父子进程不同&#xff1a; 进程id、返回值、各自的…

AI写作革命:重塑创作未来

人工智能写作技术&#xff1a;革新创作方式的智能利器 人工智能写作技术&#xff08;AI写作技术&#xff09;是指利用自然语言处理&#xff08;NLP&#xff09;、机器学习&#xff08;ML&#xff09;等人工智能技术&#xff0c;辅助或自动化完成文本的创作、编辑与优化。这一技…

法律大语言模型(Legal LLM)技术架构

目录 摘要 1 法律AI大模型技术架构 1.1 核心架构分层 1.2 法律知识增强机制 2 关键技术突破与对比 2.1 法律专用组件创新 2.2 性能对比(合同审查场景) 3 开发部署实战指南 3.1 环境搭建流程 3.2 合同审查代码示例 4 行业应用与挑战 4.1 典型场景效能提升 4.2 关…

深入理解 C# Razor Pages:构建现代 Web 应用的利器

在现代 Web 开发中&#xff0c;选择合适的框架至关重要。ASP.NET Core 提供了多种开发模式&#xff0c;其中 Razor Pages 因其简单性、高效性和易用性&#xff0c;成为构建页面导向 Web 应用的首选方案。相比于传统的 MVC&#xff08;Model-View-Controller&#xff09;模式&am…

AgenticSeek 本地部署教程(Windows 系统)

#工作记录 Fosowl/agenticSeek&#xff1a;完全本地的 Manus AI。 部署排错参考资料在文末 或查找往期笔记。 AgenticSeek 本地部署教程&#xff08;Windows 系统&#xff09; 一、环境准备 1. 安装必备工具 Docker Desktop 下载地址&#xff1a;Docker Desktop 官网 安装后启…

后台管理系统八股

项⽬地址&#xff1a;https://github.com/Xiaodie-888/Frontend.git 前端 https://github.com/Xiaodie-888/backend.git 后端 技术栈&#xff1a;Vue3ViteTyprscriptPiniaElement-plusVue-RouterExpress.jsMySQL 核⼼⼯作与技术&#xff1a; 基础组件封装&#xff1a;基于 Ele…

014校园管理系统技术解析:构建智慧校园管理平台

校园管理系统技术解析&#xff1a;构建智慧校园管理平台 在教育信息化快速发展的当下&#xff0c;校园管理系统成为提升学校管理效率、优化校园服务的重要工具。该系统集成院校管理、投票管理等多个核心模块&#xff0c;面向管理员、用户和院内管理员三种角色&#xff0c;通过…

SpringBoot2.3.1集成Knife4j接口文档

首先要查看项目中pom文件里面有没有swagger和knife4j的依赖&#xff0c;如果有的话删除&#xff0c;加入以下依赖 <!-- swagger --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</…

Abaqus/CAE操作介面

Abaqus/CAE操作介面: • 完全整合建模、分 析、工作管理與結 果評估。 • 對於Abaqus的各系 統&#xff0c;提供最完善的 介面。 • 使用中立的資料庫 檔案&#xff0c;獨立於硬體 設備。 • 客製化&#xff0c;成為應用 於特定問題之系統 。 • 選 單 (menu) 、圖 標 (ico…

垂起固定翼无人机应用及技术分析

一、主要应用行业 1. 能源基础设施巡检 电力巡检&#xff1a;适用于超高压输电线路通道的快速巡查&#xff0c;实时回传数据提升智能运检效率。 油田管道监测&#xff1a;利用长航时特性&#xff08;1.5-2小时&#xff09;对大范围管道进行隐患排查&#xff0c;减少人力巡…

DPDK与网络协议栈

DPDK与网络协议栈 DPDK简介实现使用DPDK收发数据通过UDP收发数据通过 TCP 收发数据 DPDK简介 DPDK 是是 Intel 提供的数据平面开发工具集&#xff0c;为&#xff08;IA&#xff09;处理器架构下用户高效的数据包处理提供函数以及驱动支持&#xff0c;不同于 Linux 下是以通用性…

51c大模型~合集134

我自己的原文哦~ https://blog.51cto.com/whaosoft/13956141 #Foveated Instance Segmentation 解决XR算力瓶颈&#xff0c;FovealSeg框架实现毫秒级IOI分割 本文共同第一作者为纽约大学研究生 Hongyi Zeng 和Wenxuan Liu。合作作者为 Tianhua Xia、Jinhui Chen、Ziyun…

基于51单片机和8X8点阵屏、独立按键的填充消除类小游戏

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 使用的是普中A2开发板。 【单片机】STC89C52RC 【频率】12T11.0592MHz 【外设】8X8点阵屏、独立按键 效果查看/操作演示&#x…