博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌
主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。
🍅文末获取源码联系🍅
👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟
2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅
Java项目精品实战案例《100套》
Java微信小程序项目实战《100套》
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
一、前言介绍: 随着信息技术的飞速发展,特别是互联网和移动通信技术的普及,数字化阅读逐渐成为人们获取知识和信息的重要方式。在这样的背景下,电子图书以其便捷性和丰富性受到了广泛欢迎。随着电子图书市场的不断扩大,书籍的种类和数量也在急剧增加,这为用户挑选书籍带来了挑战。为了解决信息过载的问题,个性化推荐系统应运而生,并逐渐成为在线阅读平台不可或缺的一部分。基于用户历史行为数据进行推荐的协同过滤算法尤为流行。处理庞大的用户群体和海量的图书数据需要强大的计算能力,传统的单机计算模式已无法满足需求。Hadoop作为一个开源的分布式计算平台,以其高容错性、高扩展性和对大数据处理的优秀能力,成为大数据分析的首选工具。因此,利用Hadoop来构建电子图书推荐系统,不仅可以有效处理和分析大规模数据集,提升推荐质量,还能保证系统的可扩展性和稳定性。
基于Hadoop的豆瓣电子图书推荐系统的研究与实现能够为用户提供更加精准和个性化的阅读推荐,从而优化用户体验,提高用户满意度和平台黏性。通过分析用户的历史阅读行为和偏好,系统可以发现用户的阅读模式,进而推荐更符合个人兴趣的书籍,帮助用户节省筛选时间,增强阅读效率。对于电子图书平台来说,一个高效的推荐系统可以促进更多优质内容的分发,增加用户流量和书籍销量,从而带动平台的经济效益。该系统的建立还有助于推动数据挖掘和机器学习技术在实际应用中的发展,为相关领域提供宝贵的实践经验和研究成果。最后,随着数据处理技术的不断进步,该研究还可以为未来电子图书推荐系统的改进提供理论基础和技术支持,具有长远的研究和应用价值。
二、功能设计: 系统的功能设计是整个系统的运行基础,是一个把设计需求替换成以计算机系统的形式表示出来。通过对豆瓣电子图书推荐系统的调查、分析和研究,得出了该系统的总体规划,这是开发设计系统的初步核心。如下图所示:
爬虫数据集展示:
三、功能实现: 当人们打开系统的网址后,首先看到的就是首页界面。在这里,人们能够看到系统的导航条,通过导航条导航进入各功能展示页面进行操作。系统首页界面如图5-1所示:
在注册流程中,用户在Vue前端填写必要信息(如用户名、密码等)并提交。前端将这些信息通过HTTP请求发送到Java后端。后端处理这些信息,检查用户名是否唯一,并将新用户数据存入MySQL数据库。完成后,后端向前端发送注册成功的确认,前端随后通知用户完成注册。这个过程实现了新用户的数据收集、验证和存储。注册页面如图5-2所示:
图5-2注册详细页面
豆瓣高分:在豆瓣高分页面的输入栏中输入书名、作者、出版社和标签进行查询,可以查看到豆瓣高分详细信息,并进行评论或收藏操作;豆瓣高分页面如图5-3所示:
图5-3豆瓣高分详细页面
个人中心:在个人中心页面可以对个人中心、修改密码、我的发布、我的收藏等进行详细操作;如图5-4所示:
在登录流程中,用户首先在Vue前端界面输入用户名和密码。这些信息通过HTTP请求发送到Java后端。后端接收请求,通过与MySQL数据库交互验证用户凭证。如果认证成功,后端会返回给前端,允许用户访问系统。这个过程涵盖了从用户输入到系统验证和响应的全过程。如图5-5所示。 用户管理功能在视图层(view层)进行交互,比如点击“查询、添加或删除”按钮或填写用户信息表单。这些用户表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改或删除用户信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便用户功能可以看到最新的信息或相应的操作反馈。如图5-7所示:
图5-7用户管理界面
豆瓣高分管理功能在视图层(view层)进行交互,比如点击“查询、添加、删除或爬取数据”按钮或填写豆瓣高分信息表单。这些豆瓣高分表单动作被视图层捕获并作为请求发送给相应的控制器层(controller层)。控制器接收到这些请求后,调用服务层(service层)以执行相关的业务逻辑,例如验证输入数据的有效性和与数据库的交互。服务层处理完这些逻辑后,进一步与数据访问对象层(DAO层)交互,后者负责具体的数据操作如查看、修改、查看评论或删除豆瓣高分信息,并将操作结果返回给控制器。最终,控制器根据这些结果更新视图层,以便豆瓣高分功能可以看到最新的信息或相应的操作反馈。如图5-8所示:
图5-8豆瓣高分管理界面
管理员进行爬取数据后,点击主页面右上角的看板,可以查看到系统简介、书名、作者统计、价格统计、出版社、评分统计、豆瓣高分总数、豆瓣高分信息等实时的分析图进行可视化管理;如图5-9所示:
图5-9看板界面
四、库表设计: 表4-11:豆瓣高分
字段名称
类型
长度
字段说明
主键
默认值
id
bigint
主键
主键
addtime
timestamp
创建时间
bookname
varchar
200
书名
author
varchar
200
作者
cover
longtext
4294967295
封面
laiyuan
varchar
200
来源
wordcount
int
字数
salesprice
double
价格
chuban
varchar
系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知
AI大模型探索之路-训练篇2:大语言模型预训练基础认知
AI大模型探索之路-训练篇3:大语言模型全景解读
AI大模型探索之路-训练篇4:大语言模型训练数据集概览
AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化
AI大模型探索之路-训练篇6:大语言模型预训练数据准备-预处理
AI大模型探索之路-训练篇7:大语言模型Transformer库之HuggingFace介绍
AI大模型探索之路-训练篇8:大语言模型Transformer库-预训练流程编码体验
AI大模型探索之路-训练篇9:大语言模型Transformer库-Pipeline组件实践
AI大模型探索之路-训练篇10:大语言模型Transformer库-Tokenizer组件实践
AI大模型探索之路-训练篇11:大语言模型Transformer库-Model组件实践
AI大模型探索之路-训练篇12:语言模型Transformer库-Datasets组件实践
AI大模型探索之路-训练篇13:大语言模型Transformer库-Evaluate组件实践
AI大模型探索之路-训练篇14:大语言模型Transformer库-Trainer组件实践
AI大模型探索之路-训练篇15:大语言模型预训练之全量参数微调
AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA
目录 系列篇章💥前言一、QLoRA 总体概述二、QLoRA原理解释(4-bit NormalFloat)三、QLoRA代码实践学术资源加速步骤1 导入相关包步骤2 加载数据集步骤3 数据集预处理1)获取分词器2)定义数据处理函数3)对数据进行预处理 步骤4 创建模型1、PEFT 步骤1 配置文件2、PEFT 步骤2 创建模型 步骤5 配置训练参数步骤6 创建训练器步骤7 模型训练步骤8 模型推理 总结 前言 在深度学习的不断进步中,大型语言模型(LLMs)的预训练和微调技术成为了研究的热点。其中,量化技术以其在模型压缩和加速方面的潜力备受关注。本文将深入探讨QLoRA(Quantized Low-Rank Adaptation)技术的原理、实践及应用。
一、QLoRA 总体概述 QLoRA技术是一种创新的量化LoRA(Low-Rank Adaptation)的技术,旨在保持模型性能的同时,显著减少模型的内存占用。该技术的核心包括:
1)4bit NormalFloat(NF4): 这是针对正态分布权重设计的一种信息理论上最优的数据类型。相较于传统的4-bit整数和4-bit浮点数,NF4为正态分布数据提供了更优异的实证性能。
2)双量化:QLoRA采用一种独特的双重量化机制,对初次量化后的常量进行二次量化,进一步压缩存储空间。
3)分页优化器:使用NVIDIA统一内存特性,该特性可以在在GPU偶尔OOM的情况下,进行CPU和GPU之间自动分页到分页的传输,以实现无错误的 GPU 处理。该功能的工作方式类似于 CPU 内存和磁盘之间的常规内存分页。使用此功能为优化器状态(Optimizer)分配分页内存, 然后在 GPU 内存不足时将其自动卸载到 CPU 内存,并在优化器更新步骤需要时将其加载回 GPU 内存。
二、QLoRA原理解释(4-bit NormalFloat) 前面篇章中我们有介绍,通常为了减少GPU的使用,我们会对模型进行量化处理,减少资源的使用;int8、int4量化是一种有效的模型压缩技术,它通过减少数值的精度来换取计算效率的提升,同时尽量保持模型的准确性。
1)常规int8量化和反量化过程:
2)常规int4量化和反量化过程:
3)QLoRA的NF4量化
是一种特殊的4位浮点数(Normal Float 4-bit)量化方法。它不仅定义了一种新的数据类型,还采用了基于分块的分位数量化策略,这种方法能够更有效地保持数值的相对关系,并且减少了由于量化引入的误差。QLoRA的NF4量化通过双重量化进一步减小了缓存占用,并且结合低秩适配器(LoRA)进行模型微调,可以在有限的计算资源下达到较高的性能水平。
2023 年底的时候,我就发过了 《Flutter 上了 Apple 第三方重大列表,2024 春季 iOS 的隐私清单究竟是什么?》 相关内容,如果你还对隐私清单等相关要求不了解,建议先看看前文。
如果你已经有相关了解,并且近期也提交过 App 到 App Store ,那么你可能已经收到过类似 「ITMS-91053」 的相关警告邮件,这就是隐私清单里的「必要理由的 API 声明」,也是隐私清单里最大家最容易遇到的问题之一,主要包括了:
File timestamp APIsSystem boot time APIsDisk space APIsActive keyboard APIsUser defaults APIs 邮件里也写明了,最后的要求期限是 5 月 1 号,所以正如去年说的那样,春季过去后,也是时候面对隐私清单的适配要求了。
实际上在 Flutter 进度里,官方和主流的插件基本都已经完成了隐私清单的适配要求,而目前主要出现在 Upcoming third-party SDK requirements 列表的插件,还没适配动静的应该就是 fluttertoast 了,尽管已经有了 PR #489 ,但是暂时还没有相关回应。
不过问题不大,最多自己 fork 一个 merge 下。
另外针对之前所说的,对于 “收集” 的定义目前很模糊的问题,类似 webview_flutter ,webview_flutter 本身不收集任何内容,但是App 可以用来 webview_flutter 收集浏览历史记录,然后这如何在 SDK 的隐私清单里去体现?
官方的回复是,如果SDK没有收集任何数据,那么应该提供一个隐私清单,概述没有收集任何信息,所以这也是 webview_flutter 等插件目前的适配逻辑之一。
一、认识红黑树 1.1 什么是红黑树? 红黑树是一种二叉搜索树,与普通搜索树不同的是,在每个节点上增加一个“颜色”变量 —— RED / BLACK 。
通过对各个节点颜色的限制,确保从 根 到 NIL ,没有一条路径会比其他路径长出两倍。
(NIL :表示叶子节点的空指针,统一设置为 BLACK )
1.2 红黑树的性质 根节点一定是黑色不能出现两个连续的红色节点对于同一高度而言,从根到该高度任一节点的简单路径上的黑色节点的数量相同 1.3 红黑树节点定义 二、红黑树 2.1 红黑树定义 template<class K, class V> class RBTree { typedef RBTreeNode<K, V> Node; private: Node* _root; }; 2.2 插入 红黑树的插入是我们学习红黑树过程最重要的知识之一,它主要分为两部分:平衡二叉树的插入 和 旋转 —— 调整树形结构。
插入部分与普通搜索树没有本质区别,这里不做过多介绍。
声明一下:代码中的 grandfather 和 图中的 grandparent 为同一东西,笔者在基本结束本篇时发现这里差异。
插入部分 bool Insert(const pair<K, V> kv) { if (_root == nullptr) { _root = new Node(kv); _root->_col = BLACK; // 根一定为黑色节点 return true; } Node* cur = _root; Node* parent = nullptr; while (cur) { if (cur->_kv.
面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode) 思路1:先计算出链表的长度,在将链表中的值存在数组中,在返回第k个节点。
思路2:利用快慢指针,先让快指针走k步,在让快慢指针分别同时走,当快指针走到空的时候,慢指针就是倒数第k个节点。
链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 思路:先使用快慢指针找到来链表的中间节点,在将中间节点之后的链表倒置(注意倒置之后,中间链表的前一个节点依然指向尾结点),最后遍历链表,判断链表是否是回文结构。
160. 相交链表 - 力扣(LeetCode) 思路:先分别计算出两个链表的长度,算出它们长度之间的差值deference,再让长度较长的链表先走deference步,这样两个链表的长度就会相等,再进行遍历链表,找出相交点(注意,在寻找相交点的时候要找节点的地址,不能找节点的val值)。
141. 环形链表 - 力扣(LeetCode) 思路:使用快慢指针,如果fast或者fast->next为空的话说明链表不是一个环形链表,如果fast节点等于slow节点的话,说明fast追上了slow节点(fast一定会追上slow节点,这个结论会在下文解释到),也就说明了链表会进入一个环形的链表。
环形链表的几种情况:
那么,我们就要提出几个问题:
1.为什么一定会相遇,有没有可能错过,永远也追不上?
2.fast节点走3步,4步,或者n步是否可以与slow指针相遇?
先来解答第一个问题:
假设slow进入环的时候slow与fast节点的距离为N,fast节点每次走两步,slow节点每次走一步,所以每当slow节点走一步的时候,快慢指针之间的距离就会缩小1,直到它们之间的距离变为0.
slow走的步数 fast与slow之间的距离
0 N
1 N-1
2 N-2
…… ……
x 0
第二个问题:
我们先来观察slow节点每次走1步和fast节点每次走3步时候的情况
这时候,我们需要分两种情况来分析两个指针:
a.当slow节点进入环的时候,快慢指针之间的距离N是一个偶数
b.当slow节点进入环的时候,快慢指针之间的距离N是一个奇数
slow走的步数 快慢指针之间的距离(N为偶数) 快慢指针之间的距离(N为奇数)
0 N N
1 N-2 N-2
2 N-4 N-4
…… …… ……
x-1 2 1
x 0 -1
在这里,我们发现快慢指针之间的距离N是一个奇数时,fast与slow会错过,永远也不会相遇。
但是,先别急,这个结论真的正确吗?或者我们说快慢指针之间的距离N有可能是一个奇数吗?这就需要我们再次证明一下:
我们分析一下追上与追不上的情况:
🔥 个人主页:空白诗 文章目录 🎭 引言一、基础输出函数`fmt.Print`与`fmt.Println`📌 `fmt.Print`:纯粹输出,不带换行📌 `fmt.Println`:输出后自动添加换行符 二、格式化输出`fmt.Printf`📌 基础格式化参数📌 对齐与宽度📌 特殊格式📌 实际应用示例 三、错误处理与`fmt.Errorf`四、自定义类型与`fmt.Stringer`接口五、格式化标志📌 填充与对齐📌 符号控制📌 数值格式📌 浮点数与精度📌 特殊类型与行为📌 示例整合 六、结构体与切片的格式化输出📌 结构体输出📌 切片输出📌 进阶技巧 七、自定义格式化器 `fmt.Formatter`八、总结 🎭 引言 在 Go 语言的编程世界里,fmt 包扮演着举足轻重的角色,它是格式化输入输出的强大工具箱,让你能够以清晰、美观的方式展示程序中的数据。接下来,我们将一起深入了解 fmt 包的几个核心函数,并通过实际代码示例来巩固学习成果。✨
一、基础输出函数fmt.Print与fmt.Println 📌 fmt.Print:纯粹输出,不带换行 fmt.Print是一个在Go语言中广泛使用的函数,用于将一个或多个值格式化输出到标准输出(通常是终端),并且重要的一点是它不会自动在输出结束后添加换行符。这使得fmt.Print非常适合于连续输出多条信息而不需要每次输出后都换行的场景。
package main import "fmt" func main() { // 直接输出,不换行 fmt.Print("Hello, ") fmt.Print("world!") // 输出: Hello, world! } 📌 fmt.Println:输出后自动添加换行符 fmt.Println 是Go语言标准库中的另一个常用函数,与fmt.Print相似,但它在输出一系列值之后会自动添加一个换行符(\n),这对于希望每条输出信息独占一行的场景尤为方便。
package main import "fmt" func main() { // 输出并自动换行 fmt.Println("Greetings,") fmt.Println("Earthlings!") // 输出: // Greetings, // Earthlings!
AIGC技术带给我们什么?基于AIGC原理以及技术更迭的思考
前言 AI,这个词在如今人们的视野中出现频率几乎超过了所有一切其他的事物,更有意思的是,出现频率仅次于这个词的,几乎都会加上一个修饰亦或是前缀——AI,没错,还是它。
正值五一假期,我们试着在网上搜索关键词的相应指数,分别对“ai”和“五一”两个词进行对比,我们发现:顶峰时期的”五一“一词也几乎只是达到”ai“的日常水平。(数据仅供参考,具有极强的范围局限性——尽管如此,我相信人们如今对于ai的讨论已作为家常便饭)
也许在五年前,不,三年前,AIGC这门技术还并没有起色,甚至可以说在所有技术领域之中并没有得到实际性的应用和实践。但是仅仅过了一两年——也就是在2022年11月30日,ChatGPT的发布彻底改变了人们对AI,对AIGC的看法,甚至可以说它改变了AIGC这门技术的基本含义以及实际意义。
AI是什么?这个对于我们这些臭写代码的来说并不陌生,其实它的英文本意就已经很好地解释了其功能和意义:Artificial Intelligence,人工智能,即研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。也就是说它是有助于人的。
而AIGC就是由AI自动创作生成的内容(AI Generated Content)。它即是AI的衍生学科,由AI技术赋能,为了更好地对AI进行探索和发展,人们创造了这门学科。
像我们如今使用的ai工具例如ChatGPT、文心一言、Sora等等,都是基于AIGC技术而产生的应用和服务。可见它致力于为人类提供更好的创造。
如今网络上随处可见的AI生成图片、视频、音乐,AI合成虚拟人,前段日子火爆全球的游戏《幻兽帕鲁》等等,无疑是AIGC所带给人们关注效果最为显著的杰作,也无疑是人们收益颇丰的技术支持,无论是针对开发者还是消费者。它带来了原本应是人类自身所该带来的情绪价值:歌曲的创作,某张历史图片的复原;同时也带来了无限的物质价值:开发者大赚一笔,关注者进行着无意间的流量消费以及资金开销。毫无疑问,AIGC技术给人类社会带来了众多方面的改革和变化,也实实在在地改变了人们看待周遭事物的想法。
但是,随之而来的争议也是滔滔不绝,引发的思考也是源源不断。
”AI生成的艺术作品无法取代人类情绪价值的付出“,”AI并不能取代人类千万年来在社会各个方面的创作以及思考“。人们对于AIGC技术的”入侵“,很难不表现出不适应或者说是不习惯,并且针对其引发的思考也是各执一言,各有看法。那么针对AIGC对于人类社会的浸入,我们究竟该如何看待呢?
AIGC的前世今生:历史变革与技术发展 下图很好地概括了AIGC的前世今生:
AIGC的发展理论上可以分为三个阶段:早期萌芽阶段(1950s-1990s)、沉淀积累阶段(1990s-2010s)、快速发展阶段(2010s-至今),但我认为快速发展阶段实际上可以又分为2022年前后两个阶段(ChatGPT的问世带来了新的AIGC)。
总的来说,AIGC的发展历史是随着科技水平和研究技术的改变而改变的,早期的AIGC仅仅只是局限于计算机自主创作以及简单的人机对话,但是并不成熟;后来我认为的一个里程碑事件就是手机的出现带动了语音助手的发展,例如Siri、小米的小爱同学,这些都是基于AIGC技术面向对话的成果,这很大程度表明了AIGC对于人类生活的帮助是不可忽视的,毕竟涉及到物联网、大数据、云等等,都可以与之良好结合。直到后来的ChatGPT,实际上针对这类文本创作助手,早已有相应研究和科研成果,但真正具有跨时代、开辟意义的只在OpenAI的GPT问世,它带来了一个新的变革,一个新的人机对话方式,新的AIGC。
AIGC以其多元化的应用场景、并联使用的技术融合、迎合生活的操控方式,在未来的发展必将不可限量,未来的历史也是历史,将会有更多历史性的事件等待着我们。
AIGC三把斧:AI核心技术 AI的三项核心技术包括:深度学习、神经网络和生成式对抗网络(GAN)。而由于AIGC本身就是基于AI的,所以说这三项核心技术同属于AIGC也不为过。当然,更严谨的说法包括基础模型和预训练大模型两个模块,但这是针对模型来进行分类,在此我们介绍的是技术层面。
神经网络 人工神经网络(Artificial Neural Network,即ANN ),是20世纪80 年代以来人工智能领域兴起的研究热点。它从信息处理角度对人脑神经元网络进行抽象, 建立某种简单模型,按不同的连接方式组成不同的网络。结构类似于像数据结构中的星图。
神经网络模拟的就是人类的神经网络,它的不同点犹如神经元,可以接受和传递信息,它的不同线由于神经纤维,可以控制信息的流动。
深度学习 深度学习(DL,Deep Learning)是机器学习(ML,Machine Learning)领域中一个新的研究方向,它被引入机器学习使其更接近于最初的目标——人工智能(AI,Artificial Intelligence)。
为了完善和加强神经网络,深度学习将其分为多层从而进行分工合作,犹如大脑中的不同区域负责不同的功能。这样做的目的是使机器能够更加有规律和高效地处理和理解问题。
生成式对抗网络(GAN) 近年来,深度学习在很多领域的都取得了突破性进展,但大家似乎发现了这样的一个现实,即深度学习取得突破性进展的工作基本都是判别模型相关的。2014年Goodfellow 等人启发自博弈论中的二人零和博弈,开创性地提出了生成对抗网络(GAN)。
GAN包括了一个生成模型(Generator)和一个判别模型(Discriminator),前者的作用是创造,例如文本作品、歌曲等;后者的而作用是判断,用于判断这些作品是否是真实存在的(否则是生成模型所产生的)。
可以这么理解:生成器和判别器互相对抗和挑战,从而更好地完善自己,在努力朝着生成器不被判断器识别出、判断器总是能识破生成器的方向前进——这似乎在趋于一个中间的平衡,但二者实际上是互相矛盾的。
AIGC技术在各领域的应用 我们先来探讨一下AIGC的技术应用
人工智能生成内容技术(AIGC)作为人工智能领域的重要分支,其在各个领域的广泛应用潜力难以估量。其主要的应用在于以下几个方面:
内容创作:AIGC技术被广泛应用于新闻报道、广告文案、电商商品描述等领域,能够快速生成大量高质量的内容,提高创作效率。营销推广:在商业领域,AIGC技术被用于生成个性化的营销内容,根据用户数据和行为进行精准定制,提升品牌曝光和用户参与度。客户服务:许多企业利用AIGC技术开发智能客服系统,能够自动回复用户问题、提供产品信息和解决常见问题,提升客户服务效率。教育领域:AIGC技术被应用于智能辅导系统,能够根据学生的学习情况生成个性化的学习内容,提高学习效果。医疗领域:在医疗影像诊断和疾病预测方面,AIGC技术也发挥着重要作用,能够帮助医生更准确地诊断疾病和制定治疗方案。 不知道你是否能够看出来,对于应用的介绍是使用ChatGPT写出来的。不夸张地说,它确实将AIGC的应用进行了大致的概括,并且较为全面——这也基于我给它提供的几个提示词:简短、以序号形式——是的,仅仅是如此简单的几个词,我们就可以对其语言风格以及输出内容进行控制和管理。而这,实际上就是AIGC的最为核心的应用,可以说AIGC技术就是围绕它来展开的——内容创作。
1.内容创作 像例如ChatGPT这类的文字创作工具,它们被用于内容创作,服务的对象是整个人类群体——因为人类社会离不开文字。音乐、影像同样是这样。
在生成式AI技术的使用中,又包括以下几个方面:
1) 文本生成 不可否认的是,AI生成的速度相较于人类作者更快、更高效,而生成内容的质量也是基于已有的数据支持,具有一定的权威性和真实性。在文本上的使用通常会有益于作家、博客、代码编写者等等。对于他们来说,AIGC助手的帮助让他们写作的效率大大提高,避免了冗长不必要的内容书写,并且还能帮助他们润色自己的文章,提高代码的可读性和健壮性等。除此之外,由于AI对于数据的收集范围之广,甚至能够轻松地通过各种面向人类的考试,例如心理类,法律类等等,所以它同样也可以勉强担当一个心理治疗师、律师甚至是朋友(当然,只要你可以接受你的朋友只是一个对话框)。
2) 音频生成 包括语音合成、音乐创作和声音设计等等,Suno等音乐创作 AI 程序允许用户使用 AI 创建原创音乐曲目。经过观察,我们会发现AI赋能音乐创作确实能够出现某些效果超群、技术高超的编曲,例如这首原本传统的《春天在哪里》,作为音乐爱好者,不得不说它的爵士乐味道十足,并且似乎还有自己独到的见解。
【suno ai】春天在哪里,但是ai版_哔哩哔哩_bilibili
除了音乐创作之外,语音合成和声音设计等等,也是AIGC技术在音频方面不可忽视的应用。
3) 图像生成 将草图转换为数字绘制的图像,其实本质上起到修饰的作用,但是延伸出了包括视觉艺术、广告设计、游戏场景等等方面的创作协助,这无疑给众多行业带来一个巨大的Pandora’s box,毕竟还有那么多的美术创作者,或许还在为如何塑造好的线条美感而烦恼,而如今AIGC已经较好地解决了这个问题。
4) 视频生成 人工智能生成的视频同样不能忽视,虽然目前仅仅支持无声视频,这实际上并不等同于完整的视频;如今市面上出现的许多由AI独立生成的具有指定风格的视频,让人难以辨认其真假(指是否为人创作);而事实上,这个问题在整个AIGC的应用中都频频出现,这是难以避免的。
5) 跨模式生成 AIGC中的跨模态内容生成是指使用基础AIGC模型跨多种模态生成新内容。它包括文本到图像、图像到文本、文本到代码、文本到视频、文本到音频等。像ChatGPT提供的语音对话助手,它基于文本创作,再结合了人类说话的特点,可以模仿人类的口吻完成对话,甚至连话语之间的吸气声也不会漏掉,这就是文本到音频的跨模式生成的典型例子。
一、什么是顺序表 概念:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 如下图:
优点:访问速度比较快,在给定下标的情况下时间复杂度低至O(1)
因此,顺序表适用于经常进行 下标查找 或者 更新 的操作
那么下面我们就来试着自己实现一个顺序表MyArrayList,并实现基础的增删查改的操作吧
二、MyArrayList的实现 1、定义MyList接口 public interface MyList { // 新增元素,默认在数组最后新增 void add(int data); // 在 pos 位置新增元素 void add(int pos, int data); // 判定是否包含某个元素 boolean contains(int toFind); // 查找某个元素对应的位置 int indexOf(int toFind); // 获取 pos 位置的元素 int get(int pos); // 给 pos 位置的元素设为 value -> 更新 void set(int pos, int value); //删除第一次出现的关键字key void remove(int toRemove); // 获取顺序表长度 int size(); // 清空顺序表 void clear(); // 打印顺序表, void display(); boolean isFull(); } 2、MyArrayList实现接口 1、定义成员变量与构造方法
🚀DeepSeek发布V2模型!GPT-4的性能白菜的价格
- 在 MT-Bench 中排名顶尖,与 LLaMA3-70B 不相上下,并且胜过 Mixtral 8x22B。
- 专注于数学、编码和推理。
🔗 国产开源MoE指标炸裂:GPT-4级别能力,API价格仅百分之一-CSDN博客
⚖️全国首例“AI外挂”案公开宣判
- 被告人因提供“AI外挂”被判有期徒刑三年,缓刑五年,并处罚金。
- 被告人非法获利共计629万余元,支付给程序制作者的费用高达数十万。
- “AI外挂”程序被认定为破坏性程序,对多款游戏进行未授权操作,干扰游戏正常环境。
🌐新加坡政府组织的首届 GPT-4 提示工程大赛冠军总结4 种提示词技巧!
- 借助 CO-STAR 框架构建高效的提示
- 利用分隔符来分节构建提示
- 设计含有 LLM 保护机制的系统级提示
- 仅依靠大语言模型分析数据集,无需插件或代码 — 实际案例分析 Kaggle 的真实数据集
- 总结的 CO-STAR 框架,在让 LLM 做一些内容尤其是写作类任务时非常简单有效。
🔗 https://blink.csdn.net/details/1694824
💻Google推出由 Gemini 驱动的网络安全产品 - 可识别和防御网络钓鱼攻击。
- 通过其广泛的用户和网络监控,可将检测到的恶意活动与具体的攻击活动联系起来,发现威胁。
- 借助Gemini,可将不明代码上传,利用其AI分析功能,全面审查并生成情报报告。
🔗 https://blink.csdn.net/details/1694809
🔍ChatGPT.COM 域名启用 其搜索产品预计本周上线
- OpenAI启用ChatGPT.COM域名,预示即将推出基于ChatGPT的搜索引擎。
- 搜索引擎可能利用ChatGPT的先进语言模型技术,提供更自然、更准确的搜索体验。
- 市场对ChatGPT搜索引擎表现出高度期待,或成为谷歌的潜在竞争对手。
🔗 https://chat.
📝个人主页:哈__
期待您的关注 目录
一、AOP简介
二、AOP个人浅谈
三、AOP中几个核心的方法注解
四、AOP中几个核心的属性
1.切入点(PointCut)
五、代码演示
1.SpringBoot引入依赖
2.定义一个AOP,也就是切面类 3.使用自定义注解进行增强
六、AOP实现的原理
一、AOP简介 AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。
在传统的业务处理代码中,通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码仍然会分散到各个方法中。这样,如果想要关闭某个功能,或者对其进行修改,就必须要修改所有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错率。
为了解决这一问题,AOP思想随之产生。AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。这种采用横向抽取机制的方式,采用传统的OOP思想显然是无法办到的,因为OOP只能实现父子关系的纵向的重用。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。
可以看看类和切面的关系,图片来自黑马程序员。
行了,到了这一步了也不就在废话了,我在尽量不使用太多专业术语的情况下尽可能给大家讲明白AOP。
二、AOP个人浅谈 在我们传统的OOP(面向对象编程)时,在我们原有的方法上我们希望做一些修改,我们希望啊,在执行这个方法之前通知我们的老板,告诉他我已经开始执行任务啦,不要再催促我了。在方法执行结束后,我还要把执行结果告诉老板。那么你会怎么做,是如下边的代码一样吗?
这样子做的确没问题,但是你有没有想过,如果我们的老板比较认真,每一项任务都要向老板汇报,那么你这样写代码还方便吗?如果你只有几项任务的话还好说,就是累一些,但如果你有五十项,一百项呢?
这时AOP就凸显出它的优点了。如果看了简介不明白什么是AOP,那么现在来看看我的理解。
你有很多的任务,你无法把每一项任务都向老板汇报。这时有着这样的一个组织,这个组织可以帮你和老板进行沟通,如果你想对你任务进行这样的能力增强,你就要告诉这个组织,你需要他们的帮助。什么意思呢?我用一张图来解释。
你需要AOP给你提供的帮助,你就需要向AOP提供你要进行业务能力增强的方法的路径,AOP找到这个方法就会对方法进行增强,在你调用方法的时候就会进行增强。
这下你总能理解什么是AOP了吧。
三、AOP中几个核心的方法注解 下边的代码我只使用的Around,其他的注解大家可以看看其他文章,或者自己试一下。
四、AOP中几个核心的属性 1.切入点(PointCut) 切入点就是用来描述我们到底要对哪个方法进行增强的,我们需要提供一串切入点需要的表达式。
切入点表达式的规则如下。
execution(modifier? ret-type declaring-type?name-pattern(param-pattern) throws-pattern?) modifier:匹配修饰符,public, private 等,省略时匹配任意修饰符ret-type:匹配返回类型,使用 * 匹配任意类型declaring-type:匹配目标类,省略时匹配任意类型 .. 匹配任意的包及其子包name-pattern:匹配方法名称,使用 * 表示通配符 * 表示所有的方法set* 匹配名称以 set 开头的方法param-pattern:匹配参数类型和数量 () 匹配没有参数的方法(..) 匹配有任意数量参数的方法(*) 匹配有一个任意类型参数的方法(*,int) 匹配有两个参数的方法,并且第一个为任意类型,第二个为 int 类型throws-pattern:匹配抛出异常类型,省略时匹配任意类型 下边的PointCut注解就传入了一个切入点表达式。
@Pointcut(value = "execution(* com.example.shardingsphere.controller.*.*(..))") 五、代码演示 1.SpringBoot引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 2.
目录
前言:
画布:
折线图 (Line Chart):
前言: 前端中的数据可视化是指将大量数据以图形或图像的形式在前端页面上展示出来,以便用户能够更直观地理解和分析这些数据。数据可视化是一种强大的工具,它利用了人类视觉系统的能力,使我们能够更容易地识别模式、趋势和关系,这在纯文本或数字表格中可能不太明显。
以下是关于前端数据可视化的一些关键点:
数据展示:前端数据可视化最直接的作用是将复杂的数据集转换为直观的图形,如柱状图、折线图、饼图等。这些图形使得用户可以快速地获取数据的关键信息,而无需深入研究详细的数据集。
交互性:前端数据可视化通常包含交互功能,如悬停提示、数据点点击事件、缩放和平移等。这些交互功能增强了用户体验,并允许用户更深入地探索数据。
动态更新:前端数据可视化可以实时或根据用户输入进行动态更新。例如,用户可以通过筛选器或滑块来调整显示的数据范围,图表会即时更新以反映这些更改。
数据驱动的设计:在前端开发中,数据可视化通常与后端服务相连,后端提供实时数据,前端负责将这些数据以图形方式呈现出来。这种数据驱动的设计使得前端页面能够动态地展示最新的数据。
易于理解:通过颜色、大小、形状等元素,前端数据可视化可以帮助用户更快地理解数据的含义和关系。比如,使用红色到绿色的颜色渐变来表示从负面到正面的数据变化。
故事讲述:数据可视化不仅用于展示数据,还可以用于讲述故事。通过动画、交互和视觉层次结构,可以有效地传达数据的背后意义,帮助用户更好地理解数据的来龙去脉。
技术实现:在前端实现数据可视化时,通常会使用专门的库或框架,如D3.js、Chart.js、ECharts等。这些工具提供了丰富的图表类型和交互功能,使得开发者能够轻松地创建复杂的数据可视化。
响应式设计:前端数据可视化还需要考虑不同设备的显示效果。响应式设计可以确保图表在不同屏幕尺寸和分辨率下都能保持清晰可读。
总的来说,前端中的数据可视化是一种强大的信息展示工具,它能够将复杂的数据集转换为直观、易懂的图形,从而帮助用户更好地理解和分析数据。
Chart.js 是一个流行的 JavaScript 图表库,它提供了多种数据分析图来帮助开发者创建交互式的图表。
<canvas>画布: <canvas>是HTML5中引入的一个新元素,它提供了一个空白的画布,允许开发人员使用JavaScript在上面动态地绘制图形、图像、动画等。以下是对<canvas>元素的详细说明:HTML <canvas> 标签 (jb51.net)
基本用途: 绘制基本形状:如直线、矩形、圆形等。绘制图像和文本:可以将图像加载到canvas中,并使用JavaScript控制其位置和大小;同时也可以在画布上绘制文本。创建动画效果:通过JavaScript定时器和动画循环来创建动态效果。数据可视化:适用于创建图表、地图等数据可视化应用。使用方法: 在HTML中添加<canvas>标签,并设置其宽度(width)和高度(height)。使用JavaScript获取<canvas>元素的引用,并通过getContext('2d')方法获取2D渲染上下文。使用渲染上下文提供的API进行绘图操作,如设置颜色、填充形状、描边等。特性与注意事项: <canvas>默认大小为300x150像素,但建议在标签内明确设置所需的宽度和高度。在较老的浏览器中(如IE9之前),<canvas>可能不被支持。为了兼容性,可以在<canvas>标签内添加替代内容,这些内容将在不支持<canvas>的浏览器中显示。<canvas>的内容是通过JavaScript动态生成的,因此不支持像HTML图片那样直接通过alt属性提供替代文本。对于无障碍性(accessibility)的考虑,可能需要额外的措施来提供描述性内容。与其他技术的比较: 与Flash等插件技术相比,<canvas>是HTML5的原生元素,无需额外安装插件即可使用。与SVG(可缩放矢量图形)相比,<canvas>更适合于绘制复杂的动态图形和游戏,而SVG更适合于需要高度交互性和可伸缩性的图形应用。 综上所述,<canvas>是一个功能强大的HTML5元素,它允许开发人员通过JavaScript在网页上动态地绘制各种图形和动画效果。
折线图 (Line Chart): 折线图(Line Chart)是一种常见的数据可视化图表,它主要用于展示数据随时间或其他连续变量的变化趋势。在前端开发中,折线图通常用于网页或应用程序中,以图形化的方式呈现数据,帮助用户更直观地理解数据的变化规律。
以下是关于前端折线图的一些详细说明:
基本构成:
数据点:折线图由一系列的数据点组成,每个数据点表示在某个特定时间点或连续变量值上的数据值。连接线:数据点之间通过连接线相连,形成一条连续的折线,展示了数据的变化趋势。 特点:
趋势展示:折线图非常适合用于展示时间序列数据,可以清晰地看出数据随时间的变化趋势。简洁明了:相比于其他类型的图表,折线图更加简洁明了,能够直观地反映数据的变化情况。 应用场景:
股票价格:展示股票价格随时间的变化情况,帮助投资者分析股票走势。销售额统计:展示公司销售额随时间的变化情况,帮助管理者分析销售趋势和市场需求。气温变化:展示气温随时间的变化情况,帮助人们了解气候变化和季节性规律。 前端实现方式:
HTML5 Canvas:使用HTML5的Canvas API可以在网页上绘制折线图。通过Canvas的绘图功能,可以自定义折线图的样式、颜色、数据点等。SVG:可缩放矢量图形(Scalable Vector Graphics,SVG)是另一种在前端绘制折线图的方式。SVG是基于XML的矢量图形语言,可以通过定义路径、线条、形状等元素来绘制折线图。图表库:为了更方便地实现折线图的绘制,开发者通常会使用一些流行的前端图表库,如Chart.js、Highcharts、ECharts等。这些库提供了丰富的配置选项和交互功能,可以轻松地创建出美观且功能强大的折线图。 交互功能:
鼠标悬停提示:当鼠标悬停在数据点上时,可以显示该点的具体数据值或相关信息。数据区域缩放:允许用户通过鼠标拖拽或选择特定区域来放大查看该区域内的数据变化情况。数据点点击事件:为数据点添加点击事件,当用户点击某个数据点时执行相应的操作,如显示更多详细信息或跳转到相关页面。 响应式设计:为了确保折线图在不同设备和屏幕尺寸上都能良好地显示,前端开发者通常会采用响应式设计。这意味着折线图的尺寸、布局和样式会根据屏幕大小和分辨率进行自动调整,以提供最佳的用户体验。
以下是一个简单的折线图示例,使用了流行的JavaScript图表库Chart.js。你可以直接在HTML文件中通过CDN引入Chart.js的脚本。以下是一个简单的HTML页面,它包含了一个使用Chart.js创建的折线图:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>折线图示例</title> <!-- 引入Chart.js --> <script src="
文章目录 一、背景介绍二、模型介绍2.1 模型结构2.2 模型超参数2.3 SwiGLU 三、代码分析3.1 模型结构代码3.2 FairScale库介绍 四、LLaMA家族模型4.1 Alpaca4.2 Vicuna4.3 Koala(考拉)4.4 Baize (白泽)4.5 Luotuo (骆驼,Chinese)4.6 其他 参考资料 LLaMA(Large Language Model Meta AI)模型,是由 Meta AI 发布的一个开放且高效的大型基础语言模型, LLaMA-1 共有 7B、 13B、 33B、 65B(650 亿)四种版本。其数据集来源都是公开数据集,无任何定制数据集,保证了其工作与开源兼容和可复现,整个训练数据集在 token 化之后大约包含 1.4T 的 token。 关于模型性能,LLaMA 的性能非常优异:具有 130 亿参数的 LLaMA 模型「在大多数基准上」可以胜过 GPT-3( 参数量达 1750 亿),而且可以在单块 V100 GPU 上运行;而最大的 650 亿参数的 LLaMA 模型可以媲美谷歌的 Chinchilla-70B 和 PaLM-540B。
关于训练集,其来源都是公开数据集,无任何定制数据集,保证了其工作与开源兼容和可复现。整个训练数据集在 token 化之后大约包含 1.4T 的 token。其中,LLaMA-65B 和 LLaMA-33B 是在 1.4万亿个 token 上训练的,而最小的模型 LLaMA-7B 是在 1万亿个 token 上训练的。
目录
一、属性注入
二、构造方法注入
小结:构造函数的注入
三、Setter注入
四、三种注入的优缺点分析(面试题)
1、属性注入
优点:
缺点:
2、构造方法注入(Spring4.X推荐)
优点:
缺点:
3、Setter注入(Spring3.X推荐)
优点:
五、@Autowired存在问题
1、引入Autowired的错误代码:
(1)属性注入:
(2)构造方法注入:
(3)Setter方法注入:
(4)启动类代码:
2、Autowired查找依赖顺序:
3、解决方案
(1)解决方案一:根据名称去查
(2)解决方案二:给想要拿到的对象加上@Primary注解
(3)解决方案三:加@Qualifier注解,指定引入的依赖对象
(4)解决方案四:加@Resource注解
4、@Autowired 与 @Resource 的区别(常见面试题)
六、Spring IoC&DI 的总结
1、Spring,Spring Boot 和 Spring MVC的关系以及区别
(1)Spring
(2)Spring MVC
(3)Spring Boot
(4)总结
2、bean的命名
(1)五大注解存储的bean
(2)@Bean注解存储的bean
3、常见面试题
上篇博客学习了控制反转IoC的细节,接下来就开始学习依赖注入DI的细节。
依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象。我们使用 @Autowired 注解,完成依赖注入的操作。
简单来说,就是把对象取出来,放到某个类的属性中。在一些文章中,依赖注入也被称之为 “对象注入”、“属性装配”,具体含义需要结合文章的上下文来理解。
关于依赖注入,Spring也给我们提供了三种方式:
1、属性注入(Field Injection)
2、构造方法注入(Construct Injection)
3、Setter 注入(Setter Injection)
一、属性注入 属性注入是使用 @Autowired 实现的,将UserService 类注入到UserController类中,UserService 类代码如下:
@Service public class UserService { public void doService() { System.
目录
关于数据感应
BaseDataList 类
范例运行环境
pageview 方法
设计
实现
调用示例
数据源
调用
小结
关于数据感应 数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,本文将继续介绍以与数据库提取数据并捆绑控件为例,讲解 C# 创建适用于 BaseDataList 类(如DataGrid)的通用分页数据显示方法。
BaseDataList 类 BaseDataList 类是包括如 DataList 、DataGrid 服务器控件的基类,本文我们以 DataGrid 服务器控件控件,并结合 MS SQL SERVER 和 达梦数据库,以数据分页的形式,绑定 DataGrid进行显示。
更多 BaseDataList 类的介绍请参照如下链接:
https://learn.microsoft.com/ZH-CN/dotnet/api/system.web.ui.webcontrols.basedatalist?view=netframework-4.8.1&viewFallbackFrom=net-7.0
范例运行环境 操作系统: Windows Server 2019 DataCenter
.net版本: .netFramework4.7.1 或以上
开发工具:VS2019 C#
数据提取:在这里我们以能够支持 MS SQL Server 2016、国产达梦数据 8 的通用数据库内容提取方法为例, 生成数据源需要利用 ADO.NET 中的数据提供者对象包括IDbConnection、IDbCommand、IDbDataParameter等,如何使用这些对象请参考我的文章:
《C#实现 IDbConnection / IDbCommand 等相关通用数据接口》
pageview 方法 设计 pageview 方法内置了分页函数写法(目前支持 MS SQL Server 2016 和国产达梦 8 数据库 ),另外传递SQL关键命令及配置相关参数,将数据源分页感应到指定的 BaseDataList 类控件上,其参数说明如下表:
接续上文,在这篇文章将继续介绍在Java中关于文件操作的一些内容 【Java】文件操作
文章目录 一、“流”的概念1.“流”的分类1.1输入流和输出流1.2字节流和字符流 ==字节和字符的区别?====为什么要有字符流?==1.3节点流和处理流 ==字符流自带缓冲区,为什么还要用字符缓冲流?==2.“流”的特性3.“流”的分类 二、Stream流(字节流)1.InputStream流版本一(无参)read()版本二 read(byte[] b)版本三 read(byte[] b,int offset,int len) 2.OutPutStream流 三、Stream流(字符流)readerwriter 四、 scanner 一、“流”的概念 “流”是一个抽象的概念,是对输入输出设备的一种抽象理解,在Java中,对数据的输入输出都是以“流”的的方式进行的。“流”具有方向性,输入流、输出流是相对的。当程序需要从数据源中读入数据的时候就会开启一个输入流,相反,写出数据到某个数据源目的地的时候也会开启一个输出流。数据源可以是文件、内存或者网络等
1.“流”的分类 “流”序列中的数据可以是未经加工的原始二进制数据,也可以是经过一定编码处理后符合某种格式的特定数据,因此java中的“流”分为以下三种流:
按数据流的方向:输入流、输出流按处理数据单位:字节流、字符流按功能:节点流,处理流 1.1输入流和输出流 “流”具有方向性,输入流、输出流是相对的
输入与输出是相对于应用程序而言的,比如文件读写,读取文件是输入流,写文件是输出流,这点很容易搞反。
1.2字节流和字符流 字节流:数据流中的最小的数据单元是字节,一次读入读出8位二进制;
字符流:数据流中的最小的数据单元是字符,一次读入读出16位二进制,java中的字符是Unicode编码,一个字符占用两个字节。
字节和字符的区别? 存储方式: 字节(byte):字节是计算机存储和通信的基本单位。在Java中,一个字节由8位(bit)组成,可以表示256种不同的状态,其取值范围是-128到127(对于byte类型)。
字符(char):字符用于表示文本信息。在Java中,一个字符使用Unicode编码,占用2个字节(16位)的空间。因此,Java中的char类型可以表示65536种不同的字符。
表示范围: 由于字节只有8位,其表示范围相对较小,只能表示-128到127之间的整数,或者0到255之间的无符号整数。
字符类型则能表示更多的字符,包括各种文字、符号等。由于使用了Unicode编码,Java中的char类型可以表示世界上几乎所有的字符。
为什么要有字符流? 在UTF8 编码中,“爱吃南瓜的北瓜”对应的字节如下
如果使用字节流处理中文,如果一次读写一个字符对应的字节数就不会有问题,一旦将一个字符对应的字节分裂开来,就会出现乱码了。为了更方便地处理中文这些字符,Java就推出了字符流。
用途: 字节主要用于处理二进制数据、图像、音频、视频等非文本信息,或者在网络通信中传输数据。
字符则主要用于处理文本信息,如字符串、文件名、用户输入等。
在Java中,经常需要将字节和字符进行转换。例如,当我们从文件或网络读取数据时,通常得到的是字节流,而我们需要将其转换为字符流以便进行文本处理。这时,可以使用Java提供的解码器(Decoder)将字节转换为字符。反之,当需要将文本信息写入文件或发送到网络时,需要将字符转换为字节,这时可以使用编码器(Encoder)。
区别 字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。用一句话说就是:字节流可以处理一切文件,而字符流只能处理纯文本文件。字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。 1.3节点流和处理流 节点流:节点流可以从一个特定的数据源读写数据,如FileInputStream ,FileOutputStream ,FileReader ,FileWrite 处理流:对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能,例如BufferedInputStream(缓冲字节流)
在诸多处理流中,有一个非常重要,那就是缓冲流。
我们知道,程序与磁盘的交互相对于内存运算是很慢的,容易成为程序的性能瓶颈。减少程序与磁盘的交互,是提升程序效率一种有效手段。缓冲流,就应用这种思路:普通流每次读写一个字节,而缓冲流在内存中设置一个缓存区,缓冲区先存储足够的待操作数据后,再与内存或磁盘进行交互。这样,在总数据量不变的情况下,通过提高每次交互的数据量,减少了交互次数。
联想一下生活中的例子,我们搬砖的时候,一块一块地往车上装肯定是很低效的。我们可以使用一个小推车,先把砖装到小推车上,再把这小推车推到车前,把砖装到车上。这个例子中,小推车可以视为缓冲区,小推车的存在,减少了我们装车次数,从而提高了效率。、
需要注意的是,缓冲流效率一定高吗?不一定,某些情形下,缓冲流效率反而更低
字符流自带缓冲区,为什么还要用字符缓冲流? 尽管字符流已经具备了缓冲的功能,但字符缓冲流(BufferedReader 和 BufferedWriter)仍然有其自身的优势和用途:
缓冲区大小可控:字符缓冲流提供了更大的缓冲区,可以指定缓冲区的大小。较大的缓冲区可以一次性读取或写入更多的字符数据,减少对底层I/O的频繁访问,提高读写效率。
提供了更方便的读写方法:字符缓冲流提供了一些便捷的方法,如 readLine() 方法可以一次读取一行数据,而不需要一个字符一个字符地读取。newLine() 方法可以写入一个平台特定的换行符,而不需要手动处理不同操作系统的换行符。
支持预读取和回滚:字符缓冲流具有 mark() 和 reset() 方法,可以在读取过程中进行标记(mark)并在需要时回滚(reset),方便进行预读取和回溯操作。
Spring Gateway的简介 在微服务架构的世界里,如同繁星点点的服务需要一个指挥家,将它们有序地组织起来,让它们能够和谐地协同工作。这个指挥家,就是Spring Gateway。它是一个基于Spring Framework 5、Project Reactor和Spring Boot 2.0的API网关。
如果你还不熟悉这些概念,那就把Spring Gateway想象成一座大桥,它连接了用户和服务,负责将用户的请求路由到正确的服务,同时还能够对请求进行各种处理,如过滤、限流等。
在微服务架构中,Spring Gateway的地位就如同城市中的交通枢纽,承载着信息的高效流动。然而,如何才能让这座桥梁发挥出最大的功效呢?这就需要我们对Spring Gateway进行合理的配置,下面,我们就来详细讲解这一部分的内容。
Spring Gateway的配置 接下来,我们将详细讲解如何配置Spring Gateway。配置是使用Spring Gateway的第一步,也是非常重要的一步。首先,我们需要在项目的pom.xml文件中引入Spring Gateway的依赖。下面是一个简单的示例:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> 以上依赖声明告诉Maven,我们的项目需要使用Spring Cloud Gateway,Maven会自动下载并引入所需的库。
接着,在我们的application.yml或者application.properties文件中,我们需要配置Spring Gateway的相关参数。例如,我们可以配置路由规则,指定某个路径的请求应该转发到哪个服务。下面是一个简单的示例:
spring: cloud: gateway: routes: - id: user_route uri: lb://user-service predicates: - Path=/user/** 以上配置告诉Spring Gateway,所有路径以/user开始的请求都应该转发到名为user-service的服务。这只是Spring Gateway的基本配置,实际上,Spring Gateway还提供了许多高级的配置项,例如过滤器、限流规则等,我们将在后续逐一介绍。
有了这些基本的配置,我们就可以在我们的项目中使用Spring Gateway了。但是,Spring Gateway的功能远不止于此,接下来,我们将介绍Spring Gateway的一些核心功能,如路由、过滤、限流等。
Spring Gateway的核心功能 在成功配置了Spring Gateway之后,我们可以开始探索它的一系列核心功能了。这些功能包括路由、过滤、限流等。
首先,我们来看看路由功能。路由是Spring Gateway的基石,它决定了请求会被发送到哪个服务。在Spring Gateway中,我们可以通过配置文件或者Java代码来定义路由规则。下面的代码就是一个简单的路由规则示例:
@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("path_route", r -> r.path("/get") .uri("http://httpbin.org")) .
1. 写在前面 自从OpenAI在2022年11月30日发布了引领新一轮AI革命浪潮的产品ChatGPT以来,大模型和生成式AI这把大火在2023年越烧越旺,各种技术和应用层出不穷;而2023年11月,同样是OpenAI CEO山姆·奥特曼(Sam Altman)被开除后有回归,这100小时的宫斗赚足了媒体和世界网名的关注,引出了大家对AI安全的遐想和担忧。
以OpenAI开始,以OpenAI收尾,至此已经两年有余了。这一年AI做出了令人瞩目的成绩,确似乎才刚刚开始。我、我的朋友、我的同事以及网络上的网友,都切实可行的从AI技术上获得了效率和便捷性大幅度提升的好处。
做为一名技术人,在2023年,笔者也参与了各种学习和实践,从大语言模型、多模态算法,文生图(Stable Diffusion)技术,到prompt工程实践和搭建文生图(Stable Diffusion)webui实操环境。在此对谈谈对大模型和AI的认识与思考,是为总结。
2. 生成式AI元年 2023无疑是生成式AI的元年,英伟达的CEO黄仁勋曾说过:人工智能已经到了iPhone时刻;或许离真正的AGI还有一定的距离,但AI确实展现出人类基本常识和推理的能力,特别是模型越来越大的加持虾出现的涌现能力。就在最近Google发布最新人工智能模型Gemini,声称性能超越GPT-4和人类专家,从宣传视频上看,Gemini已经具备人类的视觉(图像识别),听觉(语音识别)和自然语言理解的基本技能。
我们一起来回顾下生成式AI的发展。
2.1 GPT的发展 如果说大语言模型存在一个分水岭的话,我觉得是2017年Google提出了一种全新的模型Transformer,Transformer是典型的encoder-decoder结构,最早是用来做机器翻译的。Transformer中最重要的结构是Multi-Head的Self-Attention机制。在Transformer之前,自然语言处理(NLP)一般采用循环神经网络RNN,以及变种如双向的RNN、LSTM和GRU等,但都存在一定的问题,如长文本序列上下文遗忘,难以并行等,而Transformer较好的解决了这些问题。
Transformer推出之后,被循序了应用到自然语言处理的各个领域,同样也在机器视觉领域和传统的CNN一较高下,并拔得头筹。Transformer的火爆可见一斑,值得一提的当前Transformer的几个作者都开始加入大模型创业浪潮,虏获资本的厉害,如Adept、Essential AI、Cohere。
说回到Transformer的生态树,Transformer之后,出现了三个较大的分支:
一个是以BERT为代表的以decoder-only的模型,还有百度的ERNIE
另一个是以GPT为代表的encoder模型,还有谷歌的Bard,claude,cohere,百度的ERNIE 3.0(当前的文心一言)
第三个分支则是encoder+decoder的模型(就是整个Transformer),这里有清华系的GLM和chatGLM,还有谷歌的T5,Meta的LLAMa
BERT以完形填空的方式开启的大语言的预训练模型之路,一个pre-trained Model可以快速的迁移后下游的任务。而GPT走的是另外一条更艰难的道路,生成式模型,预测下一个词,一开始GPT1性能不如BERT,于是GPT开始了大,更大,最大的模式,从GPT1的1.17亿参数量到GPT3的1750亿参数量,开始了大力出奇迹的真正大模型之路。
在GPT3中,使得提示(Prompt)的重要性越来越被重视,逐步变成当前的Prompt Engineering。Prompt engineering是创建提示或询问或指导像ChatGPT这样的语言模型的输出的指令。它允许用户控制模型的输出并生成文本根据他们的具体需求量身定制。如何有效清晰明确的表达你的意愿,对于使用大模型是至关重要的。
在GPT3之后,OpenAI做了不同的调优,如针对代码的Codex,特别是InstructGPT引入了强化学习的机制来使得大语言模型的生成结果和人类进行对齐,而ChatGPT是在此基础上加入了有监督的学习指导,可以说是更强的对齐(OpenAI最近成立SuperAlign超级对齐部门专门解决AI和人类的对齐问题)。至此ChatGPT问世,GPT4则加入多模态使得GPT可以有处理图像的能力。
2.2 开源GPT 我们知道,OpenAI在GPT3之后就采用封闭的方式不公开代码和模型,只提供API来供使用。谷歌的Bard和PaLM也是封闭的。国外大厂里只有Meta提供了大模型的开源,如OPT、BLOOM、LLaMa。
开源社区也针对公开的模型,训练更小的模型,并希望和GPT性能对齐。比较早期的有斯坦福大学的Alpaca(羊驼),清华系的ChatGLM-6B,复旦MOSS,Vicuna-13B 和mini-GPT4。
当然后续国内外也有公司开源了较小的模型,如百川2-13B,通义千问-72B(Qwen-72B)等,这些模型都可以在modelscope上下载获得。
感谢开源!
2.3 国内的GPT们 在ChatGPT爆红之后,国内的大厂们也开启GPT模式,进入百模大战模式。百度的文心一言先开始拉开序幕,还有阿里云的通义千问,华为盘古,商汤日日新,360的360智脑,京东的言犀大模型,腾讯的HunYuan大模型,科大讯飞的讯飞星火,还有chatGLM的智谱清言。
大家都在追赶GPT,目前看百度的文心一言4.0是比较接近ChatGPT,当然如何有效的评测大模型的性能也是一门学问,可以参考Holistic Evaluation of Language Models。
2.4 文生图赛道 今年除了ChatGPT这个语言生成模型比较火之外,另一个比较火的生成式AI就是Text-to-Image文生图。就是通过文字描述来生成一个和文字描述相关的图片。
Text-to-Image的代表应用是Midjourney,还有OpenAI的DALE-2和DALE-3,以及开源的Stable diffusion。
文生图可以通过文字描述来生成逼真的图画,这让许多没有绘画基础的人们带来了福音,只要你有想象力就可以。同时,文生图还开始席卷了需要图片的行业,比如游戏原画设计,logo设计,电商模特,海报设计,视频剪辑等等。
AI生成图片可以追溯到VAE,GAN,而当前最流行都是Diffusion扩散模型,这些事图生图的范式。
而文生图,就是在图生图之前加入文本的encoder,并加入图生图的过程,来影响图片的生成,借用李宏毅老师的一个框架,著名的DALE-2和Stable diffusion以及谷歌的Imagen都是套用此方法。
3. 大模型和AI应用和思考 如果说以大模型为代表的AI模型是人工智能的iphone时刻的话,那么iphone的APP有哪些?这或许是作为开发者的一个新的机会,在最近的OpenAI开发者大会上,OpenAI发布了GPTs和GPT store,通过GPTs人们可以构建自己的应用,而GPT store是针对垂直领域的大模型微调版本。另外一种形象的说法是大模型是底座操作系统,而运行上在这平台上的软件和app才刚刚开始,是为机会。毕竟大模型的训练是需要很大成本的,而开发一个APP是有可能的。
那我们如何利用这个大模型呢?
3.1 效率提升,解决业务痛点 通过分析下当前业务中的痛点和效率低下的环节,评估下是否接入成熟AI工具如ChatGPT或者文生图,当然也要考虑成本因素。这是当前比较主流的应用方式。比如游戏设计中的原画设计,可以接入Midjourney来做初稿和创意设计,来大大加快效率;视频或者文字内容创造者,可以用ChatGPT来文案设计,用Midjourney来插画或者视频素材;培训工作者如教师可以用ChatGPT来做备课工具,提升效率。
这个阶段注重和自身业务的契合点,直接使用工具解决问题。
3.2 提升易用性,做垂直应用 当前大模型的一个重要的环节是prompt(提示),不同的prompt可以有截然不同的结果,这个也是当前大模型使用的一个门槛。如何提升工具的易用性,是一个值得关注的方向。
prompt分享平台:分享不同的prompt展示平台,甚至拿prompt做为产品来销售,以及prompt培训
能不能只写简单的prompt就能有很好的结果,比较典型的就是做垂直领域的应用,总结垂直领域特别的prompt作为潜在的prompt添加到使用者的prompt之后进行简化使用
垂直领域应用:用产品思维的方式,分析垂直领域的特点,综合大模型和其他领域知识,打造更加智能化的垂直应用
文章目录 ✍一、文件的基本认识1.文件是什么?2.文本文件和二进制文件3.文件权限4.相对路径和绝对路径1.1绝对路径1.2相对路径 ✍二、文件的基本操作1.FIle的属性2.File的构造方法3.File类的方法3.1File类的获取操作3.2File类的判断操作3.3文件创建和删除3.4其他的常用方法 ✍一、文件的基本认识 1.文件是什么? 文件是计算机中的基本数据单位,也是存储在外部介质(如磁盘、光盘等)上的具有标识名的一组相关信息的集合。文件的基本结构包括文件名、文件内容以及文件属性。
文件可以是文本文档、图片、视频、音频、程序等各种类型。每个文件都有一个唯一的文件名,它用于标识和区分不同的文件。文件内容则是文件的主体部分,包含实际的数据或信息。文件属性则提供有关文件的附加信息,如创建日期、修改日期、大小、权限等。
在计算机系统中,文件通过文件系统来组织和管理。文件系统负责文件的存储、检索、保护和共享等操作。用户可以通过文件系统来创建、打开、编辑、保存和删除文件,从而实现数据的存储和传输。
文件在计算机中扮演着重要的角色,它们是数据交换和存储的主要方式之一。无论是个人用户还是企业组织,都依赖文件来保存和处理各种类型的信息。
2.文本文件和二进制文件 文本文件和二进制文件是计算机中两种主要的文件类型,它们在存储和处理数据时有着不同的特点和用途。
文本文件:
文本文件是一种由一系列字符组成的文件,通常用于存储人类可读的文本信息。文本文件中的字符通常使用ASCII、UTF-8或其他字符编码标准来表示。由于文本文件的内容是可读的文本,它们可以很容易地被人类阅读和编辑。常见的文本文件扩展名包括 .txt、.doc、.csv、.xml 等。
文本文件通常用于存储简单的文本数据,如文档、配置文件、日志文件等。由于文本文件的内容是明文的,因此它们通常用于在不同系统和应用程序之间交换数据,因为这些系统和应用程序都能够理解并处理文本数据。
二进制文件:
二进制文件则是由一系列二进制位(0和1)组成的文件,用于存储机器可读的数据。这些数据可能是程序、图像、音频、视频或其他非文本信息。二进制文件的内容通常对人类来说是不可读的,需要使用特定的软件或工具来解析和显示。常见的二进制文件扩展名包括 .exe、.jpg、.mp3、.avi 等。
二进制文件通常用于存储复杂的数据结构和程序,因为它们能够直接存储计算机能够理解的机器语言。由于二进制文件存储的是原始数据,因此它们通常比文本文件更小、更高效,并且能够更准确地表示数据。然而,由于二进制文件的格式通常是特定于应用程序或系统的,因此它们可能不如文本文件那样容易在不同的系统和应用程序之间交换。
判断文件是二进制文件还是文本文件
使用记事本打开该文件,如果不是乱码,就是文本文件。如果是乱码,就是二进制文件。
(记事本,属于把文件内容,按照文本的方式来理解)
3.文件权限 文件权限是指文件的访问控制,即哪些用户可以访问文件并执行什么样的操作。文件权限规定了用户对文件的操作权限,包括读取权限(r)、写入权限(w)和执行权限(x)。
读取权限(r):允许用户读取文件的内容。对于目录,具有读取权限的用户可以列出目录中的文件列表。写入权限(w):允许用户修改文件的内容。对于目录,具有写入权限的用户可以在目录中创建或删除文件。执行权限(x):对于普通文件,表示用户可以执行该文件。对于目录,则意味着用户可以进入该目录。 文件权限是针对每个文件或目录设置的,它规定了对应的所有者、所属组和其他用户对文件的读取、写入和执行权限。这些权限可以分别针对所有者、所属组和其他用户进行设置。例如,在Linux系统中,可以使用ls -l命令查看文件或目录的权限设置。
文件权限与用户权限共同决定了用户对文件的实际操作权限。当用户对文件进行操作时,系统会根据文件的权限设置以及用户所属的用户组来确定用户对文件的读取、写入和执行权限。
总的来说,文件权限是确保文件安全和系统稳定的重要机制,它允许管理员或文件所有者控制谁可以访问和修改文件,以及他们可以执行哪些操作。
4.相对路径和绝对路径 文件的路径(File Path)是指在计算机文件系统中用于定位和访问文件或目录的完整地址。它通常是由一系列目录名称和子目录名称组成的序列,这些名称按照它们在文件系统中的层次结构进行排列,并使用特定的分隔符(如斜杠“/”或反斜杠“\”)进行分隔。(通常使用/,因为\在字符串中容易被解析成转义字符)
文件路径可以是绝对路径或相对路径:
1.1绝对路径 绝对路径是从文件系统的根目录开始,一直到目标文件或目录的完整路径。它包含了从根目录到目标位置的所有目录和子目录的名称。绝对路径不依赖于当前的工作目录,因此它总是能够精确地定位到文件系统中的特定位置。
1.2相对路径 相对路径则是相对于当前工作目录的路径。它不需要从文件系统的根目录开始,而是从当前所在的目录开始,指定到达目标文件或目录的路径。相对路径依赖于当前的工作目录,因此如果当前工作目录改变,相同的相对路径可能会指向不同的文件或目录。
我们以D:\IDEA\IntelliJ IDEA Community Edition 2022.3.3\bin为工作目录,我们要在bin文件夹下寻找idea64.exe
相对路径:./idea64.exe。
这里的.就代表工作目录 D:\IDEA\IntelliJ IDEA Community Edition 2022.3.3\bin
绝对路径:D:\IDEA\IntelliJ IDEA Community Edition 2022.3.3\bin\idea64.exe
✍二、文件的基本操作 针对文件系统的操作, 主要是文件/目录的创建和删除, 文件的重命名等.
Java标准库中提供了一个File类, 能够完成对某一路径上的文件进行操作.
1.FIle的属性 修饰符及类型属性说明static StringpathSeparator依赖于系统的路径分隔符(/或者), String类型的表示.public static final charpathSeparatorChar依赖于系统的路径分隔符(/或者), char类型的表示.
个人主页:深情秋刀鱼@-CSDN博客 Java专栏:Java程序设计
目录
一、String
1.Java中的数据类型
2.字符串概述
3.字符串构造方法
4.字符串构造内存原理
5.字符串比较
6.字符串常见方法
二、StringBuilder 1.定义
2.常用方法
3.StringBuilder内存分析
三、StringJoiner
1.定义
2.常用方法
一、String 1.Java中的数据类型 在Java中数据类型被分为基本数据类型和引用数据类型。
基本数据类型:数值存储在自己的空间而不是堆内存或其他的空间中,如int、float、double、boolean等引用数据类型:数值存储在其他的空间,本身的空间存储的是地址值,如数组、创建的对象、字符串等。 在本节中,我们将介绍的字符串就是一种引用数据类型。
2.字符串概述 a.在Java中所有字符串的定义都在java.lang.String中,在使用String定义字符串时应先导包。 //导包 java.lang.String; //定义 String s = "abcdef"; b.字符串参与的所有运算都属于字符串的拼接操作。由于字符串的内容自创建之后就不能改变,所以每次执行字符串的拼接操作时都会在内存中重新申请空间储存拼接后的字符串。
String s1 = "abc"; String s2 = "123"; System.out.println(s1+s2);//执行结果:abc123 在执行上面的代码时一共产生了三个字符串,分别是s1("abc")、s2("123")以及拼接后新产生的字符串"abc123"。 String s1 = "abc"; s1="三连+关注"; System.out.println(s1);//执行结果:三连+关注 c.字符串的值被创建后是无法改变的,因此在执行上面的代码时并没有改变"abc"里原本的内容,而是创建了一个新的字符串"三连+关注"并重新赋值给了s1。
d.对于没有变量参与的字符串拼接操作是不同于有变量参与的拼接操作的。
如果没有变量参与,系统会检查串池,如果串池中有该字符串,直接复用,没有再开辟新的内存空间。如果有变量参与,每一行代码都会创建新的字符串。 3.字符串构造方法 a.直接定义
String s1 = "abc"; System.out.println(s1);//执行结果:abc b.通过new关键字获取一个空字符串
String s1 = new String(); System.out.println("!"+s1+"!");//执行结果:!! c.传递一个字符串,根据传递的字符串再构造一个新的字符串
String s1 = new String("
系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知
AI大模型探索之路-训练篇2:大语言模型预训练基础认知
AI大模型探索之路-训练篇3:大语言模型全景解读
AI大模型探索之路-训练篇4:大语言模型训练数据集概览
AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化
AI大模型探索之路-训练篇6:大语言模型预训练数据准备-预处理
AI大模型探索之路-训练篇7:大语言模型Transformer库之HuggingFace介绍
AI大模型探索之路-训练篇8:大语言模型Transformer库-预训练流程编码体验
AI大模型探索之路-训练篇9:大语言模型Transformer库-Pipeline组件实践
AI大模型探索之路-训练篇10:大语言模型Transformer库-Tokenizer组件实践
AI大模型探索之路-训练篇11:大语言模型Transformer库-Model组件实践
AI大模型探索之路-训练篇12:语言模型Transformer库-Datasets组件实践
AI大模型探索之路-训练篇13:大语言模型Transformer库-Evaluate组件实践
AI大模型探索之路-训练篇14:大语言模型Transformer库-Trainer组件实践
AI大模型探索之路-训练篇15:大语言模型预训练之全量参数微调
目录 系列篇章💥前言一、微调技术分类二、LoRA原理三、在哪儿增加旁路四、为什么微调少量参数就可以五、如何对A和B进行初始化六、增加旁路会增加推理时间吗?七、R值为多少合适八、如何注入LoRA九、LoRA代码实践学术资源加速步骤1 导入相关包步骤2 加载数据集步骤3 数据集预处理步骤4 创建模型1、PEFT 步骤1 配置文件2、PEFT 步骤2 创建模型 步骤5 配置训练参数步骤6 创建训练器步骤7 模型训练步骤8 模型推理 十、主路合并旁路1、加载基础模型2、加载LoRA模型3、模型推理4、模型合并5、模型推理6、完整模型保存 总结 前言 在自然语言处理领域,大语言模型的预训练-微调技术已经成为一种常见的方法。其中,LoRA(Low-Rank Adaptation)是一种新颖的微调技术,通过引入低秩矩阵来调整模型的行为,以提高模型在新任务上的表现。本文将对LoRA的原理、优势以及应用进行详细介绍。
一、微调技术分类 微调技术主要分为以下几类:
1)增加额外参数(A):这种方法是在原有的预训练模型的基础上增加一些额外的参数,以改变模型的行为。
2)选取一部分参数更新(S):这种方法是在微调过程中只更新模型的一部分参数,而不是所有参数。这可以减少计算量,提高微调效率。
3)引入重参数化(R):这种方法是在模型的参数空间中引入一些新的变化,通常是一些线性变换或非线性变换,以改变模型的行为。这种方法可以使模型在新任务上有更好的表现。
常见的参数高效微调技术有Prefix Tuning、Prompt Tuning、P-Tuning、Adapter Tuning、LoRA等
二、LoRA原理 LoRA(Low-Rank Adaptation:低秩的适配器)是一种新颖的微调技术,它通过引入低秩矩阵来调整模型的行为,以提高模型在新任务上的表现。具体来说,LoRA在原有的预训练模型中增加了两个旁路矩阵A和B,这两个矩阵的维度远小于原始模型的输入输出维度,从而实现了参数的高效微调。
三、在哪儿增加旁路 在原有的预训练模型中,可以选择在任意两个相邻层之间增加旁路矩阵A和B。这样,模型在前向传播过程中,可以通过这两个旁路矩阵来引入新的信息,从而改变模型的行为。
四、为什么微调少量参数就可以 A的输入维度和B的输出维度分别与原始模型的输入输出维度相同,而A的输出维度和B的输入维度是一个远小于原始模型输入输出维度的值,这就是low-rank的体现,可以极大地减少待训练的参数
秩表示的是矩阵的信息量,这里的“秩”特指引入的旁路矩阵的规模,即它们的行数和列数。
在LoRA技术中,我们通过引入低秩矩阵来调整预训练模型的行为,同时保留大部分原有的参数不变。这样做可以在不牺牲太多性能的前提下,显著降低模型微调时的计算成本和内存需求。
通俗化解释:“秩”:
想象一下你有一个很大的包裹,你需要通过一个小门把它送出去。但是门太小了,你必须把包裹拆成几个小包裹才能通过。在这个比喻中,大包裹就像模型的权重矩阵,小门就像我们新增的低秩矩阵,而“秩”就是这些小包裹的数量。在LoRA中,我们通过创建一些小的(低秩)矩阵来传递信息,而不是使用原始的大矩阵。这样做的好处是我们可以只关注那些最重要的信息,忽略掉不重要的信息,从而减少计算量和内存需求。
五、如何对A和B进行初始化 A和B如何初始化?
对A采用高斯初始化,对B采用零初始化的目的是,让训练刚开始时的值为0,这样不会给模型带来额外的噪声。
六、增加旁路会增加推理时间吗? 虽然增加了旁路矩阵A和B,但是由于它们的维度远小于原始模型的输入输出维度,因此在推理过程中,计算量的增加是非常有限的。
七、R值为多少合适 R值表示的是旁路矩阵A和B的秩。一般来说,R值的选择需要根据具体任务和模型结构来确定。在实际应用中,可以尝试不同的R值,以找到最佳的设置。
八、如何注入LoRA 要将LoRA应用于现有的预训练模型中,首先需要在相邻层之间插入旁路矩阵A和B。然后,在微调过程中,只需要调整这两个旁路矩阵的参数即可。这样,就可以实现模型行为的高效调整。
如上图中定义一个简单的3层的神经网络,在第1层增加旁路后效果如下:
九、LoRA代码实践 PEFT文档资料地址
1)文档地址:https://huggingface.co/docs/peft/index