技术

LLMOps 多模态LLM Python一些比较有意思的库 LLM部分技术源码学习 LangChain源码学习 通用分布式计算引擎Ray Python并发 go依赖注入 go collection gc的基本原理 golang性能分析及优化 数据湖 高性能计算与存储 Linux2.1.13网络源代码学习 《大数据经典论文解读》 三驾马车学习 Spark 内存管理及调优 Yarn学习 从Spark部署模式开始讲源码分析 容器狂占内存资源怎么办? 多角度理解一致性 golang io使用及优化模式 Flink学习 c++学习 学习ebpf go设计哲学 ceph学习 学习mesh kvm虚拟化 学习MQ go编译器以及defer实现 学习go 为什么要有堆栈 汇编语言 计算机组成原理 运行时和库 Prometheus client mysql 事务 mysql 事务的隔离级别 mysql 索引 坏味道 学习分布式 学习网络 学习Linux go堆内存分配 golang 系统调用与阻塞处理 Goroutine 调度过程 重新认识cpu mosn有的没的 负载均衡泛谈 单元测试的新解读 《Redis核心技术与实现》笔记 《Prometheus监控实战》笔记 Prometheus 告警学习 calico源码分析 对容器云平台的理解 Prometheus 源码分析 并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go channel codereview gc分析 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes扩缩容 神经网络模型优化 直觉上理解深度学习 如何学习机器学习 TIDB源码分析 什么是云原生 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 共识算法 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全访问机制 jvm crash分析 Prometheus 学习 Kubernetes监控 容器日志采集 Kubernetes 控制器模型 容器狂占资源怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes类型系统 源码分析体会 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI——容器网络是如何打通的 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 精简代码的利器——lombok 学习 《深入剖析kubernetes》笔记 编程语言那些事儿 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 如何分发计算 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 calico学习 AQS——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记 log4j学习 为什么netty比较难懂? 递归、回溯、动态规划 apollo client源码分析及看待面向对象设计 学习并发 docker运行java项目的常见问题 OpenTSDB 入门 spring事务小结 分布式事务 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型和jvm内存布局 java exception Linux IO学习 netty内存管理 测试环境docker化实践 netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker namespace和cgroup zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 深度学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM执行 git maven/ant/gradle/make使用 再看tcp kv系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 Go基础 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

架构

k8s设备管理 LLM工具栈 ddd从理念到代码 如何应用LLM 小鼠如何驾驭大象(LLM)? 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 容器和CPU那些事儿 kubevela源码分析 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 AutoML和AutoDL 特征平台 实时训练 分布式链路追踪 helm tensorflow原理——python层分析 如何学习tensorflow 数据并行——allreduce 数据并行——ps 机器学习中的python调用c 机器学习训练框架概述 embedding的原理及实践 tensornet源码分析 大模型训练和推理 X的生成——特征工程 tvm tensorflow原理——core层分析 模型演变 《深度学习推荐系统实战》笔记 keras 和 Estimator tensorflow分布式训练 分布式训练的一些问题 基于Volcano的弹性训练 图神经网络 pytorch弹性分布式训练 从混部到统一调度 从RNN到Transformer pytorch分布式训练 CNN 《动手学深度学习》笔记 pytorch与线性回归 多活 volcano特性源码分析 推理服务 kubebuilder 学习 mpi 学习pytorch client-go学习 tensorflow学习 提高gpu 利用率 GPU与容器的结合 GPU入门 AI云平台梳理 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 学习rpc BFF openkruise学习 可观察性和监控系统 基于Kubernetes选主及应用 《许式伟的架构课》笔记 Admission Controller 与 Admission Webhook 发布平台系统设计 k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? 《软件设计之美》笔记 mecha 架构学习 Kubernetes events学习及应用 CRI 资源调度泛谈 业务系统设计原则 grpc学习 元编程 以应用为中心 istio学习 下一代微服务Service Mesh 《实现领域驱动设计》笔记 概率论 serverless 泛谈 《架构整洁之道》笔记 处理复杂性 那些年追过的并发 服务器端编程 网络通信协议 架构大杂烩 如何学习架构 《反应式设计模式》笔记 项目的演化特点 反应式架构摸索 函数式编程的设计模式 服务化 ddd反模式——CRUD的败笔 研发效能平台 重新看面向对象设计 业务系统设计的一些体会 函数式编程 《左耳听风》笔记 业务程序猿眼中的微服务管理 DDD实践——CQRS 项目隔离——案例研究 《编程的本质》笔记 系统故障排查汇总及教训 平台支持类系统的几个点 代码腾挪的艺术 abtest 系统设计汇总 《从0开始学架构》笔记 初级权限系统设计 领域驱动理念 现有上传协议分析 移动网络下的文件上传要注意的几个问题 推送系统的几个基本问题 做配置中心要想好的几个基本问题 不同层面的异步 分层那些事儿 性能问题分析 用户认证问题 资源的分配与回收——池 消息/任务队列

标签

k8s设备管理 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 容器和CPU那些事儿 kubevela源码分析 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 helm 从混部到统一调度 volcano特性源码分析 kubebuilder 学习 client-go学习 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 openkruise学习 基于Kubernetes选主及应用 Admission Controller 与 Admission Webhook k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? Kubernetes events学习及应用 CRI 资源调度泛谈 如何学习Kubernetes 以应用为中心 kubernetes operator kubernetes扩缩容 serverless 泛谈 什么是云原生 自定义CNI IPAM docker和k8s安全访问机制 Kubernetes监控 Kubernetes 控制器模型 Kubernetes资源调度——scheduler Kubernetes类型系统 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 Kubernetes源码分析——从kubectl开始 kubernetes yaml配置 CNI——容器网络是如何打通的 当我在说PaaS时,我在说什么 《深入剖析kubernetes》笔记 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件

小鼠如何驾驭大象(LLM)?

2023年03月25日

简介

张宏江:大模型发展机会与挑战

  1. 当模型足够大,语料足够多的时候,涌现这件事情出现就不足为奇。这就好比把你甩到一个外语环境中,见得多听得多,根本不用专门学语法就可以学会语言,这就是语料和模型规模的重要性。看的句子多了,就懂得语法;见的世面多了,就懂得推理和逻辑。ChatGPT在认知能力上前进了一大步,通过强化学习与NLP(自然语言处理)相结合,通过人的反馈强化学习,基本解决了自然语言理解与生成问题,并且展现出人类无中生有的原创能力。PS:模型的参数量和训练数据的 token 数之间有个比例关系,只要把模型想象成数据的压缩版本就行了,压缩比总是有极限的。模型的参数量太小,就吃不下训练数据里面所有的知识;模型的参数量如果大于训练数据的 token 数,那又浪费,还容易导致 over-fitting。
  2. 人们对知识的表示和调用发生了根本性变化。从关系数据库(SQL),到互联网信息检索,科技史上每次知识表示与调用方式的跃迁,都会掀起一次巨大的技术变革。
  3. 大模型作为基础平台支撑无数智能应用。大模型在内容创意生成、对话、语言或风格互译、搜索等方面的能力,将为各应用领域带来百花齐放。而大模型基础平台,在数据层、模型层、中间层、应用层,都蕴藏着巨大发展机遇。

热议的“中国版ChatGPT”,如何理解其意义?

  1. 张亚勤:我觉得可以把GPT这个系列的生成式AI模型看作一个由大模型组成的AI操作系统,和PC上的Windows,以及移动的安卓、iOS基本具有相似的意义。一个新的操作系统出来是什么意思?下面的硬件、上面的应用都会被重构、重塑,形成一个新的生态。
  2. 生成式对话产品会颠覆搜索引擎现有的商业模式,科技公司不得不自我革命。你也会这么认为吗?我觉得不是。要是你没有这个产品的话,别人会革你的命。我们在搜索的时候,其实是在找知识,那现在有了生成式技术,它确实提供了一种找到知识的新能力。

姚志强:以前我们做的小模型,是就很像是人类的社会分工,直奔目标,比如这个算法就只做人脸识别、车牌识别,我去收集数据标注数据,然后去训练它,未来的可扩展性其实就没有很多。但现在大模型的训练,是将它真正作为一个人来训练。我们用专家知识去引导他,给他启发性的这样思维,真正的去教导他去引导他,这是出现了“涌现”现象的原因。

  1. 未来,产品和技术演进思路全都要重新迭代,可能我们不会再有所谓的语音识别、自然语言理解、图像识别这些技术分类,剩下的只有AI——你是不是一家AI公司?判断AI基础能力的标准,可能就是大模型做得如何,在这个基础上再谈其他的行业模型、场景应用。
  2. 对我们整个产品体系来说或产品架构来说其实影响不太大,更多是提升了我们的性能。原先我们可能说要不断的要在这里面添加小模型,那现在,我只要替换成一个大模型。而中间可能会有一些特殊的行业线应用我可能会变成行业模型。
  3. 我们所说的人工智能三浪,第一浪是做是做单点的AI技术,比如做人脸识别、车牌识别,这是小模型时代了;第二浪是指把很多的技术进行组合,就串联起来,做成一个业务闭环,解决客户的实际问题,这里的流程会比较长,有时候可能不会因为一个点的技术提升就会导致整个流程有很大收益;第三浪是AI将成为未来世界的入口,形成平台和生态。我们认为,现在属于二浪到三浪的共振的时期。改变未来的交互的入口,大模型确实在做这样的事情。

池建强:未来企业,AI 会成为一个生产要素。除了员工之外,还会有一批“AI 员工”。AIGC 在应用上确实是超出所有人预料,但 ChatGPT,从技术视角来看,其实没有太强冲击性。技术的发展是线性的,只是公众的感知是阶段性的。AI 发展,到现在真正有突破性成功的有 4 个阶段。

  1. 人来写规则,用人的经验来写程序。把专家的经验变成程序这个事现在业界还在实践。
  2. 机器利用数据,写少量的规则。这时候开始有一些模型,比如决策树、简单的神经网络。
  3. 机器用海量的数据,写大量的规则。这其实就是深度学习,或者叫专用大模型。广告、人脸识别就是用的这个。每个模型,只能解决一个问题。
  4. 通用大模型。海量的数据,同一个模型,解决不同的问题。形式都是 Transformer 的续写形式,但能力是多样的,比如问答、总结、扩写。

发展脉络

从分析式AI(input ==> 预测值)到生成式AI,从domain-specific到通用,从fine-tune 到Prompt。

ChatGPT成功背后的技术原因及其对生命科学领域的启发

  1. 早在上个世纪五十年代,就有学者提出了人工智能(Artificial Intelligence)的概念,其目的是希望让计算机拥有人类智能(或部分人类智能)。这个领域经过很多年的发展,依然没有突破,直到2012年出现了深度学习技术。深度学习主要解决了模型表示能力的瓶颈。我们面对的建模问题,比如图像理解、语言翻译、语音识别、分子-蛋白结合构象预测等技术,都是非常复杂的非线性问题,在深度学习出现之前,模型表示能力很弱,无法对这些复杂问题进行精确表示。而深度学习技术,可以通过模型的层次堆叠,理论上可以构建任意深度的模型,突破了模型表示能力的瓶颈,从而在语音识别、计算机视觉、自然语言理解等领域取得了突破性进展。
  2. 这个阶段的主要局限,是非常依赖于标注数据的数量。由于模型参数变多,想要求解这么多的模型参数,需要大量的训练数据作为约束。而想获得大量的标注数据非常贵,到亿级别之后就很难再有提升,数据支撑的有效模型大小也受到限制
  3. 2017年,一个重要的基础工作Transformer出现了。2019年,一个叫作BERT的工作脱颖而出,BERT采用了一个叫作自监督预训练的思路,无需标注数据仅利用文本语料本身存在的约束就可以训练模型(比如某句话的某个位置只能用某些限定的词),这样互联网上存在的优质语料不需要进行人工标定就可以用来做训练,从而一下子使得可用训练数据的数量有了巨大的提高,再配合上大模型,使得BERT模型的效果远远超过过去的模型,并且在不同任务间具有很好的通用性,成为NLP领域里程碑工作之一。其实在BERT出现之前的2018年,还有个工作叫作GPT(即GPT1.0),更早利用了自监督预训练的思路来做文本生成,即输入前面的文本,模型预测输出后面的文本,领域里面的优质语料无需标注就可以做训练。BERT和GPT都是在Transformer基础上发展而来的,而Transformer也逐渐发展成为AI领域的通用模型
  4. 在自监督预训练技术出现之后,我们可以认为新一代人工智能发展到了第二个阶段,即自监督预训练技术使得可用训练数据有了几个数量级的提升,我们进入了一切皆为训练数据的时代。这使得模型可以获得几乎无限的训练数据在训练数据大幅提升的支撑下,模型大小也有了数个数量级的提升(有效模型达到了千亿规模),(为了对如此规模的数据进行建模,模型参数的规模越大越好,更大规模的训练数据需要模型具备更强的记忆、理解和表达能力。而为了拥有更强的记忆、理解和表达能力,模型则需要更大的参数量,也就是更大的模型。)而在模型效果上,这些模型变得不再依赖于下游任务领域数据的再训练,所以,领域进入到基于自监督预训练的通用大模型时代
  5. ChatGPT为什么能有这样惊艳的效果?其中一个核心原因是ChatGPT基于生成大模型GPT3.5构建,这应该是当前自然语言理解领域文本生成最好的模型(GPT3.5比GPT3.0使用了更多的数据和更大的模型,具有更好的效果)。第二个核心原因则是基于人类反馈的强化学习技术:第一步,先收集用户对于同一问题不同答案的偏好数据;第二步,利用这个偏好数据重新训练GPT模型,这一步是基于监督信息的精调;第三步,根据用户对于不同答案的偏好,训练一个打分函数,对于ChatGPT的答案会给出分数,这个分数会体现出用户对于不同答案的偏好;第四步,用这个打分函数作为强化学习的反馈(Reward)训练强化学习模型,使得ChatGPT最终输出的答案更偏向于用户喜欢的答案。通过上述过程,ChatGPT在GPT3.5的基础上,针对用户输入,输出对用户更友好的回答。ChatGPT第一阶段训练GPT生成模型使用的训练数据非常多,大约在几十TB,训练一次模型需要花费千万美元,而第二个阶段,基于强化学习的少量优质数据反馈则只需要数万条优质数据。这种新的范式,有可能成为第三阶段人工智能的核心驱动技术,即首先基于自监督预训练的大模型,再结合基于少量优质数据反馈的强化学习、Prompting等技术,形成模型和数据的闭环反馈,获得进一步的技术突破。如果这个技术走通,那么无人驾驶、机器人以及生命科学等数据获取昂贵的领域将显著受益。
  6. ChatGPT并不能证明人工智能已经有了人类心智,ChatGPT表现出来的一些创造性和心智,是因为自然语言理解语料中包含了语义、逻辑,基于自然语言语料训练出来的生成模型,统计意义上学习到了这些对应关系,看起来似乎有了智能,但并不是真的有人类心智。ChatGPT很棒,但说他智力等于几岁小朋友的说法,都不够严谨。因为从根本上讲,人学习新知识、进行逻辑推理、想象、运动反馈这些能力,目前AI还没有具备。
  7. ChatGPT并不是一两个研究人员做出的算法突破,而是在先进理念指导下,非常复杂的算法工程体系创造出来的成果,需要在团队和组织上匹配(类比OpenAI和DeepMind)。纯研究型的团队恐怕不能成功,对深度学习理解不够、太工程化的团队也不会成功。这只团队需要:第一要有足够资源支持,可以支撑昂贵的深度学习训练和人才招聘;第二要有真正在工业界领导过工程化大模型团队的专家领导,ChatGPT不仅有算法创新,更是工程体系创新;第三,也可能是最重要的,需要一个团结协作有统一领导且不追求论文发表的组织(松散型的组织利于算法创新,但不利于工程化算法攻坚),且配备足够多优秀的工程和算法人才。

脉络:由于自然语言任务种类繁多,且任务之间的差别不太大,所以为每个任务单独微调一份大模型很不划算 ==> pre-train model ==> 如何驾驭pre-train model?(Prompt Learning & Prompt Tuning))

自然语言处理基础

上世纪 50 年代到 70 年代,人们对用计算机处理自然语言的认识都局限在人类学习语言的方式上,当时学术界普遍认为,要让机器完成 NLP 任务,首先必须让机器理解语言。因此分析语句和获取语义成为首要任务,而这主要依靠语言学家人工总结文法规则。但是人类语言既复杂又灵活,仅靠手工编写的文法规则根本无法覆盖,规则之间还可能存在矛盾。因此这一阶段,可以说自然语言处理的研究进入了一个误区。正如人类是通过空气动力学而不是通过模仿鸟类造出了飞机,事实上进行自然语言处理也未必要让机器完全理解语言。70 年代,随着统计语言学的提出,基于数学模型和统计的方法开始兴起,NLP 领域才在接下来的四十多年里取得了一系列突破。80 年代以来,随着硬件计算能力的不断提高,以及互联网发展产生的海量数据,越来越多的统计机器学习方法被应用到自然语言处理中。2006 年,基于神经网络和反向传播算法进行训练的深度学习方法开始兴起,各种神经网络模型也被引入到自然语言处理任务中。

自然语言处理(Natural Language Processing, NLP) 被誉为“人工智能皇冠上的明珠”,一方面表明了它的重要性,另一方面也突出了它的技术难度。简单来说,NLP要做的事就是利用计算机实现自然语言数据的智能化处理、分析和生成,以期让计算机实现听、说、读、写、译这些人类所具备的语言能力。

  1. 词表示。没有思考过 Embedding,不足以谈 AI
    1. synonym and hypernym。用一个词相关的词来表示一个词
    2. one-hot。假定所有的文字一共有 N 个单词(也可以是字符),我们可以将每个单词赋予一个单独的序号 id,那么对于任意一个单词,我们都可以采用一个 N 位的列表(向量)对其进行表示。 缺点:这样会导致词汇与词汇之间是没有任何关联的。
    3. represent word by context。词通常有多重含义,需要根据单词出现的上下文以不同的向量表示同一个词
    4. word embedding。基于神经网络的词的向量表示方法。
  2. 关键词的提取,关键词,顾名思义,就是能够表达文本中心内容的词语。
    1. 基于统计特征的方法
    2. 基于词图模型的关键词提取
    3. 基于主题模型的关键词提取
  3. 语言模型。语言模型是根据语言客观事实而进行的语言抽象数学建模,是一种对应关系。根据前文预测下一个词是什么:计算一个序列的词成为一句话的概率是多少;根据已经出现的词,计算某个词出现的概率
    1. 统计语言模型。本质是基于词与词共现频次的统计。给定一个句子 S=w1,w2,w3,…,wn,则生成该句子的概率为:p(S)=p(w1,w2,w3,w4,w5,…,wn),再由链式法则我们可以继续得到:p(S)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|w1,w2,…,wn-1)。那么这个 p(S) 就是我们所要的统计语言模型。有一个非常本质的问题并没有被解决,那就是语料中数据必定存在稀疏的问题,公式中的很多部分是没有统计值的,那就成了 0 了,而且参数量真的实在是太大了。
      1. N-gram,前面出现的N个词,出现xx概率多大。但是如果 n 比较大,或者相关语料比较少的时候,数据稀疏问题仍然不能得到很好地解决。这就好比我们把水浒传的文本放入模型中进行统计训练,最后却问模型林冲和潘金莲的关系,这就很难回答了。因为基于 ngram 的统计模型实在是收集不到两者共现的文本。
    2. 神经网络语言模型。a neural language model is a language model based on netual networks to learn distributed representations of words. 给每个词分别赋予了向量空间的位置作为表征,从而计算它们在高维连续空间中的依赖关系。

有没有一种方法,可以把语言变成一种数学计算过程,比如采用概率、向量等方式对语言的生成和分析加以表示呢?之前很方案都是基于 符号、统计的,引入神经网络之后,一般用一个向量表示一个词,向量是学习出来的,并且可以根据新的语料学习调整。

什么是语言模型?其实每个人都用到过语言模型,那就是拼音输入法。拼音输入法的本质就是一个语言模型,用户给定一串拼音之后,比如“wo he ni”,每个拼音下都有很多的候选汉字,多个拼音就会组合爆炸,屏幕上不可能把所有组合展示出来让用户选,只能展示一个或几个最可能的汉字组合。可能性如何判断?这就要用到中文语言模型,任意一个中文串,语言模型可以给出这个中文串是一个正常人类句子的概率大小。比如“我和你”是正常人类句子的概率要明显大于“窝核腻”、“我喝泥”等等,所以最终给用户呈现“我和你”。此外,现代输入法通常都有联想功能,当你输入“wo he ni”之后,输入法不止能猜到你想输入“我和你”,还会给出后面的联想“我和你一起”,这也是基于语言模型。给定前面若干个单词,预测下一个单词是什么;然后模型将预测的单词加入到给定单词序列,继续预测下一个;如此递归直到预测下一个单词为结束符号或达到要求长度。如果一开始给定的单词序列为我们提问的一个问句,我们认为它的后续输出为问题的答案,那这个语言模型就变成了一个问答系统,ChatGPT的本质正是如此。

机器怎么看懂人类的文字?

语言模型编码了关于语言的统计信息。简单来说,统计信息告诉我们在给定上下文中,某个内容(例如单词、字符)出现的可能性有多大。

OPENAI首席科学家llya:大型语言模型的理念是:如果有一个大型神经网络,我们可以对其进行训练,让它根据前面的文本内容预测下一个单词。再看最初的猜想:也许生物神经元和人工神经元极为类似,没有太大区别。那么,如果有一个可以准确预测下一个单词的大型神经网络,它的运转方式也许类似于人们谈话时生物神经元的运转方式。如果我们和这样的神经网络对话,因为它能够准确预测下一个单词,所以可以在理解对话的基础上,准确地缩小生成对话的可能性范围。精确猜测下一个单词需要进行预测,这也是理解的方式。我们很难清楚定义神经网络的“理解“,但我们可以轻易测量和优化网络对下一个单词的预测误差。我们想要神经网络拥有“理解”能力,但能做的是优化预测。通过优化预测得到了目前的大型语言模型,它们都是用强大的反向传播算法训练的神经网络。

llya:专业化训练 vs 通用训练?在某些情况下,专业化训练肯定能发挥巨大作用。我们进行通用化训练的原因仅仅是为了让神经网络能够理解我们所提出的问题。只有当它具有非常强大的理解能力时,我们才能进行专业化训练,并真正从中受益。所以,这两种训练方向都有前景。在开源领域,人们已经开始进行专业化训练,因为他们使用的模型性能较弱,所以要尽可能地提升模型的性能。我们可以将AI看成是由多个元素组成的集合,每个元素都能对其性能作出贡献。在特定任务中,专业数据集可以使AI表现得更好;从所有任务角度出发,性能更强的基础模型无疑也更有用。所以答案就是:我们不必非要二选一,也可以将两者结合起来。

李宏毅-BERT and its family

以往的NLP任务都是为每个任务分配一个模型,之后用对应任务大量的标注数据去训练这个模型。Transformer出世后,模型对文字上下文的理解能力得到显著增强

  1. 首先,用无标注的数据(可以理解为一段普通的文字)训练一个预训练模型。在这个环节里,我们培养模型文字接龙的能力,也就是给定前k个词,模型能预测出第k+1个词。(pre-training)。
  2. 然后,在模型能够理解文字含义的基础上,用有标注的数据训练模型去定向做一些下游任务。例如文本分类,文本相似性比较等。有标注的数据集是远小于无标注数据集的,在这个环节,我们只是对模型做了一些微小的调整。(fine-tuning)。 这个过程和人类学习语言的过程是十分接近的。比如考托福考试,需要有听说读写这些测试。但是人类的学习的过程并不是直接去学习这些题目的做法,而是通过阅读大量的英文语料去掌握英文,之后再学习这个题目的解法,达到解题的效果。

Pre-training

给出一段文本,OpenAI 就能返回给你一个 Embedding 向量,这是因为它的背后是 GPT-3 这个超大规模的预训练模型(Pre-trained Model)。

  1. 这个 API 可以把任何你指定的一段文本,变成一个大语言模型下的向量,也就是用一组固定长度的参数来代表任何一段文本。
  2. 提前计算“好评”和“差评”这两个字的 Embedding。对于任何一段文本评论,我们也都可以通过 API 拿到它的 Embedding。
  3. 我们把这段文本的 Embedding 和“好评”以及“差评”通过余弦距离(Cosine Similarity)计算出它的相似度。然后我们拿这个 Embedding 和“好评”之间的相似度,去减去和“差评”之间的相似度,就会得到一个分数。如果这个分数大于 0,那么说明我们的评论和“好评”的距离更近,我们就可以判断它为好评。如果这个分数小于 0,那么就是离差评更近,我们就可以判断它为差评。 PS: 对于大模型,即便没有在针对具体的业务场景进行专门的训练(比如电影评论、商品评论),以上面情感分析为例,使用预训练模型给出来的向量,直接根据距离做的判断,其准确率也很厉害了。

what is pre-train model(也被称为foundation model)? represent each token by a embedding vector. 预训练语言模型的本质是从海量数据中学到语言的通用表达。

  1. contextualized word embedding。比如bank 单词有两种或三种意思,对于不同的意思的token,会根据其经常出现的上下文,学习一个 embedding token。 相关方法如ELMO等。
  2. 不同于以往的embedding:输入一个token,输出一个embedding。contextualized word embedding是在输入一整个句子以后,输出这个句子中各个token的embedding。这样这个token的embedding就是在看过这个token的上下文后,输出token embedding,这个embedding就包含了上下文的信息。每个词的向量,随着位置以及前后词的不同,编码出来的结果是不一样的。
  3. contextualized word embedding的模型就像是一个encoder,用于编码信息。通常是非常深的网络,可以用到lstm,可以用自注意力层。

NLP任务一般又被分为自然语言理解(NLU)和自然语言生成(NLG)两大类,对应的不同的无监督预训练目标。其中,自回归(Autoregressive,简称AR)语言建模和自编码(Autoencoder,简称AE)一直是最成功的两个预训练目标。Transformer encoder是一个AE模型,Transformer decoder则是一个AR模型。

  1. AR模型,代表作GPT,从左往右学习的模型。AR模型从一系列time steps中学习,并将上一步的结果作为回归模型的输入,以预测下一个time step的值。AR模型通常用于生成式任务,优缺点如下:
    1. 优点:AR模型擅长生成式NLP任务。AR模型使用注意力机制,预测下一个token,因此自然适用于文本生成。此外,AR模型可以简单地将训练目标设置为预测语料库中的下一个token,因此生成数据相对容易。
    2. 缺点:AR模型只能用于前向或者后向建模,不能同时使用双向的上下文信息,不能完全捕捉token的内在联系。
  2. AE模型,代表作BERT,它不会进行精确的估计,但却具有从被mask的输入中,重建原始数据的能力,即fill in the blanks(填空)。测出该位置应该出现的那个正确词汇,这就意味着模型能够“吃透”上下文语义信息,是一种有效的将文本转换成高维特征的方法。AE模型通常用于内容理解任务/只需要理解输入语义的任务,比如自然语言理解(NLU)中的分类任务:情感分析、提取式问答。AE模型的优缺点如下:
    1. BERT使用双向transformer,在语言理解相关的任务中表现很好
    2. 输入噪声:BERT在预训练过程中使用【mask】符号对输入进行处理,这些符号在下游的finetune任务中永远不会出现,这会导致预训练-微调差异。而AR模型不会依赖于任何被mask的输入,因此不会遇到这类问题。且基于一个独立假设:在给定了unmasked tokens时,所有待预测(masked)的tokens是相互独立的。
  3. 针对机器翻译这种序列到序列的任务(同时需要内容理解和生成的任务/适用于需要基于输入的生成式任务),往往会将模型组织为完整的编码器-解码器架构。它将每个task视作序列到序列的转换/生成(比如,文本到文本,文本到图像或者图像到文本的多模态任务)。
    1. 理论上是结合了 GPT 和 BERT 的优点,但会带来参数的暴涨,训练成本很高,google 提出T5后并未过多发展。T5 统一了 NLP 任务的形式,一切都可以是 Text2Text 的形式,与 GPT 解决问题的思路是一致的。

在自回归生成的过程中,会为序列开始后的每个时刻生成一个词,并把它当作下一个时刻生成的上下文。这个过程可以用伪代码来表示。

def generate_text(prompt, model, max_length=100):
    # 输入一个初始的提示语,然后逐步生成文本
    output_text = prompt
    while len(output_text) < max_length:
        # 从模型中预测下一个词
        next_word = model.predict_next_word(output_text)
        # 将下一个词添加到输出文本中
        output_text += next_word
    return output_text

  BERT GPT
预训练的方式不同 双向语言模型,通过左右两侧的单词序列来预测中心单词的表示 单向语言模型,通过左侧的单词序列预测右侧的单词序列
目标不同 预测中心单词 生成下一个单词/预测下一个单词的概率分布
预训练数据集不同 主要使用了BooksCorpus和Wikipedia数据集 使用了互联网上的大规模文本数据集,包括维基百科、新闻、小说等等
模型结构不同 由多个Transformer编码器组成,最后一层会输出整个输入序列的表示 由多个Transformer解码器组成,只输出最后一个单词的表示

how to pre-train?

  1. 最早的跟预训练有关的模型,应该是CoVe,是一个基于翻译任务的一个模型,其用encoder的模块做预训练。但是CoVe需要大量的翻译对,这是不容易获得的,能不能通过一大段没有标注的语料进行预训练呢?
  2. 比较直觉的self-supervised learning就是预测下一个单词是什么。给出的解法就是将一个token输入到网络中,经过softmax之后,得到下一个token的概率分布。

  3. 其中使用LSTM(上图的model = LSTM)做predict next token的工作有elmo,以及ulmfit。
  4. 使用self-attention的方式(上图的model = LSTM)进行next token prediction。

有哪些预训练模型?

  1. Left-to-Right LM: GPT, GPT-2, GPT-3。适合文字接龙
  2. Masked LM: BERT, RoBERTa。适合文字填空
  3. Prefix LM: UniLM1, UniLM2
  4. Encoder-Decoder: T5, MASS, BART

Task-specific Fine-tuning

语言模型虽然可以对训练过的语言产生统计意义上的理解,例如可以根据上下文预测被遮盖掉的词语,但是如果直接拿来完成特定任务,效果往往并不好。因此,我们通常还会采用迁移学习 (transfer learning) 方法,使用特定任务的标注语料,以有监督学习的方式对预训练模型参数进行微调 (fine-tune),以取得更好的性能。预训练是一种从头开始训练模型的方式:所有的模型权重都被随机初始化,然后在没有任何先验知识的情况下开始训练:这个过程不仅需要海量的训练数据,而且时间和经济成本都非常高。因此,大部分情况下,我们都不会从头训练模型,而是将别人预训练好的模型权重通过迁移学习应用到自己的模型中,即使用自己的任务语料对模型进行“二次训练”,通过微调参数使模型适用于新任务。

how to fine-tune? fine-tune部分旨在根据预训练的model添加部分层从而可以解决下游任务。

如何在预训练好的模型中再加入一部分让其可以实现下游任务?现有的NLP任务的分类,其中按照输入可以分为两类,按照输出可以分为四类(one class;class for each token;copy from input;general sequence)。

输入可以分为两类

  1. one sentence; 如句子分类
  2. mutliple sentences; 比如QA,自然语言推理,需要在两个句子之间加入一个特殊的符号[SEP](转为一个句子)。

输出可以分为四类

  1. one class; BERT的解法是让一个特殊的符号[CLS]作为整个句子的表示,之后将[CLS]的embedding输入到一个分类器中,进行分类任务。也可以像其他模型一样,将所有token的embedding都输入到一个模型中(可以是各个token embedding的均值,也可以是各个token输入到RNN,再得到下一层的嵌入),进行分类。
  2. class for each token; 如果任务是对每一个token进行分类的话,就需要将每一个token的embedding输入到一个网络中,对其进行分类。
  3. copy from input。 比如说Extraction-based QA任务,其任务就是输入一段原文和一个问题,之后在原文中标注好哪个token是开始,哪个token是结尾。BERT论文中的解法就是设计了两个可以训练的embedding(一个是start,一个是end),之后用start和end向量分别和BERT得到的嵌入求内积,之后再通过softmax,计算哪个最大,就是最后的结果。
  4. general sequence。生成任务
    1. BERT可以作为一个encoder,需要我们自己去设计一个decoder,但是decoder是没有经过预训练的。
    2. 让pre-training模型当作decoder来使用,其方法就是输入一个[sep]之后让model输出一个东西,再将模型的输出作为模型的输入,以此类推,不断的得到输出结果。

如何进行fine-tune呢?大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介

  1. 全部微调:使用新的数据集对整个模型进行微调,包括预训练的部分和新加的任务特定层。这种方法通常需要大量的数据和计算资源,并且需要更长的训练时间,但能够获得最好的性能。
  2. 部分微调:只对特定的层或几个层进行微调,通常是模型的最后几层或添加的任务特定层。这种方法通常需要较少的数据和计算资源,训练时间也较短,但性能可能不如全局微调。
  3. 冻结部分层:将预训练模型的前几层(如 BERT 的前若干层)冻结,只对后面的层进行微调。这种方法可以减少微调的参数量和计算量,但可能会影响性能。
  4. 动态掩码微调:对于需要进行序列标注任务的预训练模型,可以使用动态掩码微调的方法,即只对标注序列的位置进行微调,对其他位置的参数进行冻结。这种方法可以减少微调的参数量,提高计算效率。
  5. 半监督微调:使用少量的标注数据和大量的无标注数据对模型进行微调,以提高性能。这种方法需要使用半监督学习的技术,如自监督学习或基于对抗学习的方法。
  6. Prompt 工程:更偏向应用与业务,通过修改输入给大模型的提示词,调优输出结果。 前面五种,都需要一定的操作成本,且一般由算法工程师或所谓 AIGC 工程师来完成,最后一种是在解决大模型从生产到应用的“最后一公里”问题,目前是必备的,当下一般由算法工程师或其他技术角色兼任,或是企业招聘专人负责。

主流大语言模型的技术原理细节

对于大模型的两种不同的期待

对于大模型的不同期待所衍生的两类使用方式

  1. 成为专才。比如bert(做文字填空的,所以不能“说话”)
    1. 在进行具体的任务之前需要改造:加外挂(即为模型加额外模块)和微调参数(fine tune)。
    2. 有机会在专一任务有机会跑赢通才。
  2. 成为通才。
    1. 需要额外进行prompt。
    2. Multitask learning as Question Answering。所有自然语言的处理都是问答问题。
    3. 只要重新设计 prompt 就可以快速开发新功能,不用写程序。

比如做情感分析,你可以专门做一个情感分析的模型。也可以你给一点情感分析的例子,让模型去做文字接龙。

再进一步,毕竟找范例有点麻烦,让机器根据叙述知道我们让它干嘛(instruction-tuning读懂人类的指令)。把任务用人类的语言描述出来,变成一个dataset,然后让llm 学到你让它干嘛,进而可以 generalized 到没有看过的指令上。

GPT-1到ChatGPT的演进

李沐老师的「跟李沐学 AI」 系列视频专栏分析了整个 GPT 系列的相关论文,深入浅出,形象生动,强烈推荐!

ChatGPT解析系列:GPT1、GPT2与GPT3

GPT-1到ChatGPT的演进和技术原理Transformer的出现完全打开了大规模预训练语言模型(Pre-trained Language Model , PLM)的空间,并且奠定了生成式AI的游戏规则。

  1. Transformer相比之前论文的novalty在于:大胆地抛弃了传统的CNN和RNN基础模型,整个网络结构完全是由Attention机制组成。更准确地说,Transformer由且仅由自注意力(self-Attenion)机制和前馈神经网络(Feed Forward Neural Network)组成。
  2. 从实际应用的角度来看,Transformer的主要贡献(contribution)在于以下几个方面:
  3. 突破了RNN模型不能并行计算的限制
  4. 精度和模型复杂度相比RNN + Attention系列模型更优
  5. Transformer本身也可以作为base model扩展

BERT仅使用了Transformer的编码器(Encoder)部分进行训练,而GPT-1则只使用了Transformer的解码器(Decoder)部分,实现了NLG层的统一。将海量知识融入到一个统一的模型中,而不针对每个特定任务分别训练模型,使AI解决多类型问题的能力大大加强。

  1. GPT-1: 预训练+微调模式,117M参数、12层、2亿单词。 利用 transformer 架构成功捕捉到了文本中相距较远的依赖关系。PS:GPT-1先于Bert出现。
    1. 预训练阶段:基于Transformer Decoder架构,以语言建模作为训练目标(文字接龙)。
    2. 微调阶段:将训练好的Decoder参数固定,接上一层线性层,通过有监督训练任务(分类(Classification)、文本蕴含(Entailment)、相似性(Similarity)、多选题(Multiple Choice))微调线性层的参数,从而进行预测。
  2. GPT采用Masked-Attention,对模型和训练数据的要求会更高,因为模型能读到的信息只有上文。而采用普通Attention的Bert在训练阶段就能同时读到上下文。这个性质决定了GPT模型越来越大的趋势(GPT需要把模型做大,训练数据做丰富,才能达到超越Bert的效果)。但是,长远来看,Masked-Attention是push模型更好理解文字的重要手段,毕竟在现实中,我们更希望培养模型知上文补下文,而不是单纯地做完形填空。GPT2的核心思想是:只要我的数据够多够好,只要我的模型够大够强。我可以直接去掉fine-tune,训练出一个通用的模型
  3. GPT-2的目标是试图用一个模型去做多个NLP任务,在无监督数据中包含很多有监督的任务内容,如果在无监督数据上学习的足够充分,就无需下游任务进行微调,只需将任务输入进行转化,并增加对应的提示信息,就能够进行下游任务的预测。例如在解决英译法的翻译任务时,将输入变成“翻译成法语,英文文本,法语文本”。
    1. 通俗地解释一下:语言模型实际上是一种自监督的方式,根据已知的词预测未知的词,只是不需要显示地定义哪些字段是要预测的输出。那如何用无监督多任务的训练方式实现语言模型自监督训练+多任务微调的效果呢?带有任务性质的数据集。我们只需要将input、output和task都表示为数据,例如在一个英文翻译成法语的机器翻译任务中,我们只需要将样本、标签和任务表示成(translate to french,english text,french text),就实现了对P(output|input,task)的建模。
    2. 重要的是,这种方式可以实现无监督训练,并且里面的task可以变化,也就是说现在GPT-2可以实现无监督多任务训练而不需要第二阶段分不同任务有监督的微调!所以,GPT2在训练数据上,玩出了花样。它从著名的在线社区Reddit上爬取训练数据(数据具有一定的问答特性),并按社区用户的投票结果筛选出优质的内容。
    3. 最后我们看到,GPT-2相对于GPT-1,最大的改进就是去掉了第二阶段的微调(fine-tune)层,OpenAI 在预训练过程中,将各类 NLP 任务的数据都放到 GPT-2 的训练数据中,帮助大模型更好地理解和生成文本。在经过这些步骤以后呢,GPT-2 的预训练模型在未经过任何微调的情况下,就能战胜许多下游任务的最佳结果。
  4. GPT-3 。GPT-2 “零样本学习” 的方式仍然存在一定的局限性,因为下游的使用者,很难把新的下游数据注入到模型中(PS:没见过的下游任务?)。因为 GPT-3 预训练模型的规模已经变得非常庞大了,很少有机构有能力承担微调所需的巨大算力成本。OpenAI 提出了一个更新的理念,也就是全新的“少样本学习”(Few-Shot Learning)的概念。 允许下游使用者通过提示词(prompt)直接把下游任务样本输入到模型中,让模型在提示语中学习新样本的模式和规律,这种方法的学名叫做 in-context learning。
    1. 只给提示就是zero-shot,给一个示例叫做one-shot,给少量多个示例就是few-shot。
  5. 从GPT2到GPT3,Zero-shot和Few-shot的方式被证明可以使得模型能够去除fine-tune部分,训练一个通用的语言模型,辅助少量样本可以对没见过的下游任务也有一定的能力。
  6. InstructGPT相对GPT-3要解决的是大模型的alignment(对齐)问题。积累大量指令对齐的 QA(问题-回答)训练数据,成本很高,此外大型语言模型会生成一些不真实、有毒(不符合人类道德伦理等)或对用户毫无帮助的输出,显然这些与用户期待的不一致。
    1. 大模型在预训练过程中见识了各种各样的数据,因此针对一个prompt/instruct(提示)会输出什么东西,也可能是多种多样的。但是预训练数据中出现的数据模式,不代表都是人类在使用模型时希望看到的模式,原因是 predicting the next token on a webpage from the internet is different from the objective “follow the user’s instructions helpfully and safely”,预训练阶段的目标函数与人类对LLM真实的期望不一样。因此需要一个alignment(对齐)的过程,来规范模型的“言行举止”。而实现这个过程InstructGPT引入了RLHF机制(人类反馈强化学习),实际上6年前的AlphaGo正是充分利用了强化学习,才在围棋领域实现了所到之处无敌手。简单点说,InstructGPT就是在GPT-3基础上利用RLHF机制(人类反馈强化学习)做了微调,以解决大模型的alignment(对齐)问题。
    2. 整个过程就是老师(人类标注员)先注入一些精华知识,然后让模型试着模仿老师的喜好做出一些尝试,然后老师对模型的这些尝试进行打分,打分之后,学习一个打分机器,最后打分机器就可以和模型配合,自动化地进行模型的迭代,总体思路称为RLHF:基于人类反馈的强化学习。

RLHF

万字长文详解大模型平台技术栈经过预训练之后,我们可以获得类似于 LLaMA 这样的 Base Model,但这距离 ChatGPT 这种 Assistant Model 还有一段距离。Base Model 并不能像 Assistant Model 一样能够很好的适用于指令理解、多轮聊天和 QA 问答等场景,而只是总是倾向于去续写文本。也即是说,Base Model 并不能很好的和用户的意图对齐 (Align),有可能会生成无用、甚至是有害的内容。为了解决这个问题,算法科学家们提出了很多的解决方案,典型代表就是以 InstructGPT 这种先经过 Supervised Finetuning,然后通过 Reward Modeling 和基于人类反馈的强化学习 RLHF。DeepSpeed 团队也发布了 DeepSpeed-Chat,开源了一个支持端到端的 RLHF 的训练和推理系统,复刻了 InstructGPT 论文中的训练模式,并确保三个阶段一一对应:监督微调SFT;奖励模型微调RM;基于人类反馈的强化学习RLHF。PS: 通过人类反馈进行模型微调。

RLHF——让大模型对齐人类偏好 所谓对齐人类偏好,主要体现在以下三点:有用(遵循指令的能力)、诚实(不容易胡说八道)、安全(不容易生成不合法的,有害,有毒的信息)。因此在大模型的训练阶段,如果引入人类的偏好或者人类的反馈来对模型整体的输出结果进行进一步优化,显然是要比传统的“给定上下文,预测下一个词”的损失函数要合理的多。即使用强化学习的方法,利用人类反馈信号直接优化语言模型。

为什么ChatGPT用强化学习而非监督学习?

  1. 模型通过生成答案并接收反馈来学习
    1. 在强化学习中,我们为模型提供指令,但并不提供人工编写的答案。模型需要自己生成答案。评分机制(例如人类)会读取生成的答案,并告诉模型这些答案的质量。模型的目标是如何回答以获得高分。
    2. 另一种机制是模型生成多个答案,评分机制告诉模型哪个答案最好。模型的目标是学习生成高分的答案,而不是低分的答案。
  2. 语言模型(至少)有三种交互模式:
    1. 文本型(text-grounded): 为模型提供文本和说明(“总结此文本”,“基于此文本,以色列的人口是多少”,“本文中提到的化学名称是什么”,“将此文本翻译成西班牙语”等),让模型基于我们提供的文本生成答案;
    2. 求知型(knowledge-seeking): 向模型提供问题或指导,让模型根据内在知识(“流感的常见原因是什么”)提供(真实)回答。
    3. 创造型(creative): 为模型提供问题或说明,然后让模型进行创造性输出。(“写一个关于…的故事”)
  3. 对于语言生成模型来说,监督学习/指令调优最大的问题是它们只能复制演示者给出的确切答案,但实际上,人类语言可以用多种方式传递相同的信息,它们都是切实可行的。如果因模型轻微偏离人类规定的文本而受到“惩罚”,可能会使模型产生困惑。我们当然可以继续逼迫模型去学习更难学习的遣词造句,尽管模型已经学会了生成具有同样意思、合法的替代性回答。因此,我们非常看好强化学习训练提供的多样性表达。
  4. 监督学习只允许正反馈(我们向模型展示一系列问题及其正确答案),而RL允许负反馈(模型被允许生成答案并得到反馈说“这答案是不正确的”),相比正反馈,负反馈要强大得多。
  5. 对于求知型查询,我们希望模型在对答案没把握的情况下能够如实回答“我不知道”或拒绝回答这一问题。对于这类交互模式,由于监督训练可能会让模型撒谎,所以我们必须使用RL。核心问题是:我们希望模型根据内部知识进行回答,但我们并不知道模型内部知识包含的内容。 在监督训练中,我们给模型提供问题及正确答案,并训练模型复制提供的答案。这里有两种情况:(1)模型“知道”答案。这种情况下,监督学习能够正确推动模型将答案与问题相关连,并且有望让模型执行相似的步骤,回答将来遇到的类似问题。这是所期望的行为。(2)模型不知道答案。在这种情况下,监督训练还是会促使模型给出答案。现在,我们有两种选择。一种可能是,它会促使模型记住特定的问答对。这种做法本身并没什么坏处,但不太高效,因为我们的目的是让模型具有泛化能力,并且能回答任何问题,而不只是那些在训练数据中出现的问题。但如果我们使模型在这些情况下能做到泛化,那么实际上就是在教模型捏造答案,相当于鼓励模型“说谎”,这很不好。由于我们无法确定模型知道哪些信息或不知道哪些信息,所以无法避免第二种情况,这对监督训练来说是一个真实且严重的问题。我们不能仅依靠监督学习来训练模型生成可信任回答,还需要强化学习的加持。与监督学习不同,强化学习不会鼓励模型编造答案:即使模型最初确实猜对了一些答案并错误地学习了“编造”行为,但长远来看,模型会因编造答案的得分较低(很可能是不正确的)而学会依赖内部知识或选择放弃回答。
  6. 长期以来,使用强化学习训练生成语言任务对大多数玩家来说都不切实际:由于缺乏可靠的自动评分指标,强化学习训练需要对每个训练样本进行人工反馈。这既耗时又昂贵,特别是对于需要查看数千到数万甚至数十万个示例才能学习的模型。然而,强化学习训练现在变得实用了:首先,出现了可以从较少示例中学习的大型预训练语言模型。更重要的是,这些模型为强化学习循环(RL loop)中去掉人类参与铺平了道路。监督训练对于文本相关的任务非常有效,而且大型模型可以很好地学习执行一些任务。例如,让模型确定两个文本是否意思相同,或者一个文本是否包含另一个文本中没有的事实,根据经验来看,大型语言模型(甚至中型语言模型)可以使用监督学习可靠地学习执行这些任务,这为我们提供了可用于强化学习设置的有效自动评分机制。

流程

RLHF——让大模型对齐人类偏好预训练主要针对补全能力,但不一定是“有用”的补全。RLHF优化模型所涉及的三个步骤

  1. 指令微调(SFT):模型会模仿其训练数据,使用精选的人类回答数据集来微调预训练的大语言模型以应对各种查询。这让模型获得了优异的指令理解和意图识别能力,模型的输出也更符合人类的期待,胜过通用文本生成模型。PS: chat 模型就是SFT 过的模型
    1. 指令微调SFT(Supervised fine-tuning)的数据集是问答对,即(prompt,answer)对,prompt我们可以理解为指令或问题,answer就是针对该指令或问题的高质量答案。SFT就是在预训练模型基础上利用这些人工标注的数据进一步微调
    2. IFT可以算作SFT的一个子集,或者说先驱步骤,IFT的主要目的是让模型适应并听从人类的指令,比如当指令prompt出现”summarize”时,模型就应该知道现在的任务是总结任务。经过IFT之后,模型学会了听从指令,但是其生成的内容却不一定安全可靠。所以为了提升大模型的帮助性、降低有害性,人们会继续做SFT,通过高质量的数据给模型展示无害的、有帮助性的回答,规训模型的生成内容。
  2. 奖励模型训练(RW):使用一个包含人类对同一查询的多个答案打分的数据集训练一个奖励模型。或者说,就是一个打分模型,标注者对大量的SFT模型输出进行投票,哪个更好,哪个更差,由此创建了一个由比较数据组成的新数据集。相比监督微调,这种方法的优势在于不需要标注者编写回答,只需要为模型生成的几个回答打分,大幅提高了标注效率。
    1. 训练RM的数据集包含同一提示的不同输出,其中query表示提示信息或者说指令信息,chosen为标注后排序分数较高的答案,即针对提示选择的答案;rejected为标注后排序分数较低的答案,即针对提示拒绝的答案。
       {
           "query": "联合国总部在哪里?",
           "chosen": "联合国总部大楼位于纽约曼哈顿东侧,属于xxx",
           "rejected": "联合国的15个专门机构都没有设在总部,然而,xx"
       }
      
    2. 训练RM是一个排序任务,不是直接对文本标注分数来训练奖励模型,是因为标注者的价值观不同导致这些分数未经过校准而充满着噪音,不同的排名结果将被归一化为用于训练的标量奖励值。针对query,输入chosen和rejected答案,训练目标尽可能的使得chosen答案和rejected答案的差值更大。
    3. 训练奖励模型的基本目标是获得一个模型,该模型接收一系列的文本,之后返回每个文本对应的标量奖励,该奖励会在数字值的大小上代表人类偏好,越大表示越接近人类偏好,越小表示越脱离人类偏好。
  3. 用reward model 优化sft model,用优化后的sft 生成更多比较数据,用于训练新的reward model。
    1. 人类反馈强化学习/近端策略优化算法(PPO):利用PPO算法,根据RW模型的奖励反馈进一步微调 sft model。如果没有接触过强化学习,理解这部分原理可能稍微比较困难,我们可以先简单理解有这么一个过程,只需要大概知道经过强化学习后,LLM 给出的回答会越来越逼近那些在奖励模型中得分比较高的回答。PS: 更复杂的过程包含actor模型、reference模型、reward模型和critic模型。

总结一下:我们通过比较容易获得的公开无标签数据,来训练一个大语言模型/预训练模型,然后,通过人工编写的问答对,来生成高质量的监督对话数据,来优化大语言模型的对话能力。在得到了这个优化后模型(sft model)之后,标注者便在给定问题上可以基于模型生成的答案,对回答进行排序,并用排序数据训练一个reward model对回答的结果排序打分,用来评估回答的质量。最后,也是强化学习中最重要的一步,就是用你的“奖励模型”来提升 SFT model的效果。PS:在得到一个sft model之后,如何进一步优化sft model?一种办法是准备更多的“问题回答对“,但这个成本很高,再一个准备的多了,也可能会有价值观等问题,所以干脆训练一个专门的reward model来做这个事儿,用它来对sft model 生成的内容打分,进而继续“微调”sft model。这个很像家长、老师会告诉我们做事的正确答案,但是教的不多,到社会上,没人告诉你对错,只能通过别人的脸色、反应来判断自己做的对错。

ChatGPT训练三阶段与RLHF的威力

  1. 预训练模型是一个未加控制的“怪物”,因为其训练数据来源于对互联网内容的无差别抓取,其中可能包括点击诱导、错误信息、政治煽动、阴谋论或针对特定人群的攻击等内容。
  2. 在使用高质量数据进行微调后,例如StackOverflow、Quora或人工标注,这个“怪物”在某种程度上变得可被社会接受。
  3. 然后通过RLHF进一步完善微调后的模型,使其更符合客户的需求,例如,给它一个笑脸。 你可以跳过这三个阶段中的任何一个阶段。例如,你可以直接在预训练模型的基础上进行RLHF,而不必经过SFT(Supervised Fine-Tuning,监督微调)阶段。然而,从实证的角度来看,将这三个步骤结合起来可以获得最佳性能。预训练是资源消耗最大的阶段。对于InstructGPT模型,预训练阶段占据了整体计算和数据资源的98%。可以将SFT和RLHF视为解锁预训练模型已经具备、但仅通过提示难以触及的能力。

技术

RLHF开源框架主要有DeepspeedChat、Trlx、ColossalAI-Chat,同时在这些框架中会包括一些常用的节省GPU资源,加快训练速度的框架例如Accelerate、PEFT等。在整个RLHF的优化训练中,少则涉及2个模型,多则涉及4个模型(base-model,sft-model,reward-model,ppo-model),超参数较多,训练优化存在较多不确定性。还有一个需要关注的问题,就是RLHF的优化训练耗时较多,少则半月,多则数月才会训练完成,训练资源成本较多。

一键式 RLHF 训练 DeepSpeed Chat(一):理论篇ChatGPT模型的训练是基于InstructGPT论文中的RLHF方式。这与常见的大语言模型的预训练和微调截然不同,目前仍缺乏一个支持端到端的基于人工反馈机制的强化学习(RLHF)的规模化系统,为使RLHF训练真正普及到AI社区,DeepSpeed-Chat应运而生一键式RLHF训练 DeepSpeed Chat(二):实践篇 值得细读

数据集格式

基于 LoRA 的 RLHF: 记一次不太成功但有趣的百川大模型调教经历 非常经典。 PS:大模型统一的一个好处是input字段统一,进而数据集格式统一。这不像以前的专有模型,input字段各式各样。数据集格式是什么样子,就侧重训练模型哪些方面的能力。

  1. sft 数据集/Instruction 数据集
  2. sft训练之后的大概效果是这样的:
     输入: "你是谁开发的啊"
     原始 baichuan-7B: "我就是你,我是你自己。(自性)"
     ChatBaichun-HC3: "我是一个计算机程序,由一个人或一群人编写。我的目的是帮助人们解决问题和回答问题。"
    
  3. rl 数据集,这个是训练reward model 用的,不是训练sft model 用的。

小结

流程与技术放在一起如下图

BaiChuan2技术报告细节分享&个人想法 当产出一个新的模型结构时,可以从以上视角、阶段来一一对比。PS: 提示词在不同模型之间,还是有细微差别的,那想要提示词效果比较好,自然需要了解对应模型的细节。

chatgpt 是怎么炼成的?

ChatGPT (可能)是怎么炼成的 - GPT社会化的过程 (李宏毅)

  1. 学习文字接龙
    1. 输入“你好”,gpt 可以接“美”(你好美)。当然,“你好” 后面也可以是 “嘛”,也可以是“高”。gpt 的输出是随机的,哪个在它学习的素材里出现的概率高就显示哪个。
    2. 文字接龙的学习是不需要人工标注的,网络上的每一段文字都可以教机器做文字接龙。
    3. 文字接龙有什么用?可以回答问题。你问gpt “台湾最高的山是那一座?”,gpt 可能接“玉”,你输入“台湾最高的山是那一座?玉”,它可能会接“山”。我们就知道答案是“玉山”。
    4. 你问gpt “台湾最高的山是那一座?”,gpt 也能有其它回答,比如gpt学习的素材里有一个选择题:“台湾最高的山是那一座?A 玉山;B 雪山”,也可能“台湾最高的山是那一座?谁能告诉我答案?”。这个时候chatgpt 是一个自由自在的孩子。PS:基础LLM(Base LLM)的特点是基于大量文本训练数据,来预测下一个最有可能出现的单词,缺点是不可控,容易输出有问题的文本。
  2. 人类老师引导文字接龙方向。gpt ==> chatgpt
    1. gpt 在网络上看到过各式各样奇怪的东西,可能产生各式各样奇怪的回答,不知道哪些是人类希望它回答的。
    2. 找人来思考想问gpt的问题,并人工提供正确答案。针对“台湾最高的山是那一座?”,gpt 有多个回答,然后由人来告诉它(标注) 人类想要的回答是“玉山”,人类只需要告诉机器,哪个答案是比较好的,哪个答案是比较差。
  3. 模仿人类老师的喜好
    1. 训练一个模仿人类老师的模型,teacher model: 给一个问题,再给一个gpt 提供的答案,它负责输出一个分数。它学习的目标就是模仿人类的标准/偏好。
  4. 用增强式学习向模拟老师学习
    1. 问gpt “世界最高的山是哪座?”,gpt 接了一句“世界上最深的海又在哪里?”,这是 对gpt 是一个合理的回答,但不是人类想要的。
    2. 把上述问题 和答案丢给 teacher model(已经学会了人类的偏好),teacher model 给一个score,也就是增强式学习(reinforcement learning)的reward。
    3. 接下来就是根据 reward 调整gpt的参数,目标是获取更高的score。经过reinforcement learning之后,就是chatgpt 了。

使用者感受chatgpt 的功能是:生成式学习。但chatgpt 实际做的事儿是 分类:给一句话,从所有的word 中选出一个word输出。

chatgpt 带来的研究问题

  1. 如何精准提出需求(Prompting)?它不是一个聊天机器人,它只是根据你说的话生成后面的话,得调教它,靠人工还是靠系统?
  2. 如果更正错误?chatgpt的预训练资料只有到2021年。chatgpt 在生成内容的时候,并不真正理解所生成的内容,虽然很多时候它是对的,但因为不理解所以还是会出错,甚至是一些虚假的内容,这在比如企业客服场景中是不合适的(客服场景以结果为导向,引导客户购买或者 告诉客户哪个更好,有时候需要给出标准答案,比如价格等,这个时候说不知道也比给出错误的结果强,企业很难接受不可控的输出)
  3. 侦测一段话是不是AI 生成的。
  4. 泄露机密。比如教普通人制备生物武器
  5. 限制其一次性输入的文本量:限制其在训练、推理期间与世界互动的能力 语言大模型100K上下文窗口的秘诀

其它

大(语言)模型推理原理及加速

投身LLM,要从本质上想明白的三个问题:未来是什么,哪些机会更好,我们要怎么准备 好文。

神经网络训练目标是使预测损失最小化,在各个参数展开的空间内找到最优的点,如果从头开始找,会比较慢;但是从之前已经训练好的其他类似模型开始,就相当于在最优点附近的点开始,自然收敛的速度和效果会比从零训练好得多。取预训练好的网络的部分结构和权重,与自己新增的网络部分一起训练,称为微调(fine-tune)。

从深度学习发展前10年的历程来看,模型精度提升,主要依赖网络在结构上的变革。 例如,从AlexNet到ResNet50,再到NAS搜索出来的EfficientNet,ImageNet Top-1 精度从58提升到了84。但是,随着神经网络结构设计技术,逐渐成熟并趋于收敛,想要通过优化神经网络结构从而打破精度局限非常困难。近年来,随着数据规模和模型规模的不断增大,模型精度也得到了进一步提升,研究实验表明,模型和数据规模的增大确实能突破现有精度的一个局限。

BERT由两阶段构成,每个阶段有自己的特点和目标。第一个阶段是预训练阶段,第二个阶段是Fine-Tuning阶段。预训练阶段用大量无监督的文本通过自监督方式进行训练,把文本包含的语言知识以参数形式编码到Transformer中,Fine-Tuning一般是有监督的,数据量比较小,在模型结构上做分类任务以解决当前任务。第一阶段跟第二阶段怎么连接起来的?在预训练阶段Transformer学到了很多初始化的知识,第二阶段就把初始化网络学到的语言知识拿来用,Fine-Tuning引入新的特征解决你的问题。所以,为什么BERT效果这么好?为什么以前的模型效果没有BERT好?因为,第一阶段编码了文本中大量的语言学知识,在Bert之前,没有用那么多的文本数据,而且是无监督的方式。那么我们关心的是:BERT里的Transformer到底学到了什么?比传统模型多学了什么知识?这是关键。如果归纳一下目前的研究结论的话,大致概述一下:BERT训练好之后,低层Transformer主要学习自然语言表层的特征,中层学习编码句法信息,高层编码了NLP的语义特征。很多实验都已证明这一结论。

如何利用LLM做多模态任务?

张俊林:GPT4等LLM模型具备类人智慧了吗?

  1. 一种观点认为GPT 4这种LLM模型仅仅学会了语言中的单词共现等浅层的表面统计关系,其实并未具备智能,只是类似鹦鹉学舌的语言片段缝合怪而已;另外一种观点则认为:GPT 4不仅学会了语言元素间的表面统计关系,而且学到了人类语言甚至包括物理世界的内在运行规律,文字是由内在智能产生的,所以LLM具备类人智能。
  2. 假设LLM模型训练好了,在使用时输入Prompt,GPT模型是如何把知识提取出来的?假设输入的Prompt是:“Beat music is owned by”,GPT可以通过NTP返回正确答案:Apple。这个例子里,“Beat music”是个实体,“owned by Apple”是这个实体对应的某个属性。经过研究,发现GPT在提取这条知识的时候,经历了明显的三阶段过程:
    1. 首先,单词“music”是描述这个实体最后的、也是最关键的词汇,它的信息在顺着Transformer block往上走的过程中,先通过Attention把之前的修饰语“beats”相关信息集成到“music”对应位置。之后,随着Transformer层数越来越高,通过每个Transformer Block的FFN层,不断往“music”对应的Embedding里增加信息,所以随着信息往上层流动,“music”这个单词对应层数的Embedding,能够触发越来越多的与“beats music”相关“属性”词汇。这是第一个步骤,整个过程总体发生在Transformer的低层。
    2. 第二步,GPT模型在“by”单词这个位置,也就是NTP要产生输出token的最后一个位置,通过Attention把单词“own”的信息集成到最后位置。这里需要注意一下,最后一个单词对应的Transformer位置是比较关键的,因为在它的最上层会给出Next Token输出。在推理过程中,GPT会把输入上文中的重要信息通过Attention逐步集成到这个位置上来。这个操作也发生在Transformer的低层。
    3. 第三步,在“by”单词位置,也就是最后一个位置的Transformer高层,它在低层已经集成了单词“own”的信息,这个信息在高层,通过Attention把“beats music”对应的属性“apple”提取出来。具体提取动作是通过某个Attention Head来做到的,而且这篇文章证明了Attention Head里会编码<实体-属性>信息。过去一般认为Attention主要是用来进行信息比较和搬运的,它证明了Attention也会存储某种知识。 通过以上三步,GPT完成了对某条知识的提取过程。
  3. 一个GPT知识提取的轮廓:当训练好GPT模型后输入Prompt,对于Transformer某个位置对应的输入单词,随着Transformer 不断往上走,GPT通过Attention,把这个单词上文中与自己有关的信息集成到自己的Embedding里,而每层的FFN对当前单词Embedding做变换增加信息,以此方式来不断触发FFN里存储的知识并逐层Refine单词对应的Embedding(类似上面例子里单词“music”的过程)。Transformer的last token位置也是如此,它的特殊之处在于,从底层到上层,首先会把整个输入上文中最关键的信息,通过Attention拷贝到自己的位置,之后通过这个关键信息来逐步过滤出上文中比较重要的信息。在这个位置的Transformer底层,应该有很多候选答案可供输出,正确答案排名并不靠前,随着Transformer往上走,正确答案排名越来越靠前,而且可以和正确答案竞争的候选答案越来越少,体现为分配给正确答案的概率分布得分越来越高,直到last token的最高层,GPT可以输出正确答案(类似上面例子中单词“by”的过程)。
  4. 在训练过程中,GPT模型会优先学习具备以下特性的知识点:高频知识点、通用知识点(被复用概率高的则通用)、具体而非抽象的知识点。应该遵循这三个原则。为什么会这样呢?因为根据Next Token Prediction的原则,越是高频出现的知识点,如果GPT本次预测错了,则会做反向传播修正模型参数,以保证下次再见到类似情况会预测对,高频知识点因为出现次数多,所以获得反向传播修正模型参数的次数多,也就更容易建立起对应的知识点,及其和其它知识点的连接通路。高频知识点如果学会了,在后面的训练数据会很容易碰到这个知识点,所以对降低NTP任务的loss贡献就大。其它两类知识点也是类似的道理,通用知识点因为通用性强,所以在后续预测中被使用的机会多,所以获得反向传播修正模型参数的次数也多,也容易被模型学会,具体而非抽象的知识点也因为在训练数据中见到的次数多,所以容易被建立起来。诸如此类。反过来,低频的、领域或任务专用的、抽象的知识点,就会越晚被GPT模型学会。或者说,如果想学会这类知识点,则需要让模型见到更大量的数据,以增加这些知识点在学习过程中必要的反向传播修正参数的机会