技术

Python实践 下一个平台Agent 激发LLM涌现——提示工程 LLM微调理论及实践 大佬沉思 LLM外挂知识库 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快速入门

架构

大模型推理服务框架 模型服务化(未完成) 大模型RHLF 大模型训练 大模型推理 从Attention到Transformer 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到Attention 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 组件

大佬沉思

2023年10月18日

简介

汪涛:这次的人工智能爆发一方面是算力的不断提升,另一个是Trasformer这个新算法的进步。它是CNN(神经网络)带来的深度学习算法之后又一次小的算法革命(本质上还是神经网络)。只要利用了这种新的算法,只有量的区别,不会有什么“涌现”“不涌现”的本质区别。有些是已经涌现了,而有些还没有涌现。如果只是一些量的差异,只要在量上不断改进就可趋同或超越,而如果是质的差别,就可能很长时间超越不了。PS:Trasformer 的上限决定了这一波“智能”的上限。

张俊林

通向AGI之路:大型语言模型(LLM)技术精要 值得细读很多遍。

NLP研究范式的转换

  1. 在Bert和GPT模型出现之前,NLP领域流行的技术是深度学习模型,而NLP领域的深度学习,主要依托于以下几项关键技术:以大量的改进LSTM模型及少量的改进CNN模型作为典型的特征抽取器;以Sequence to Sequence(或叫encoder-decoder亦可)+Attention作为各种具体任务典型的总体技术框架。
    1. 在这些核心技术加持下,NLP领域深度学习的主要研究目标,如果归纳一下,是如何有效增加模型层深或模型参数容量。就是说,怎么才能往encoder和decoder里不断叠加更深的LSTM或CNN层,来达成增加层深和模型容量的目标。这种努力,尽管确实不断增加了模型层深,但是从解决具体任务的效果角度看,总体而言,不算很成功,或者说和非深度学习方法相对,带来的优势不算大。
    2. 深度学习之所以不够成功,我认为主要原因来自于两个方面:一方面是某个具体任务有限的训练数据总量。随着模型容量的增加,需要靠更大量的训练数据来支撑,否则即使你能把深度做起来,任务效果也做不上去。而在预训练模型出现之前,很明显这是NLP研究领域一个严重问题;另外一个方面是LSTM/CNN特征抽取器,表达能力不够强。意思是就算给你再多的数据也没用,因为你不能有效地吸收数据里蕴含的知识。主要应该是这两个原因,阻碍了深度学习在NLP领域的成功突围。
  2. Bert/GPT这两个预训练模型的出现,无论在学术研究角度看,还是工业应用角度来看,都代表了NLP领域的一个技术飞跃,并带来了整个领域研究范式的转换。这种范式转换带来的影响,体现在两个方面:首先,是部分NLP研究子领域的衰退乃至逐步消亡;其次,NLP不同子领域的技术方法和技术框架日趋统一,在Bert出现后一年左右,技术栈基本收敛到两种技术模式中。关于这两点,我们分头来谈。
    1. 中间任务的消亡。典型的中间任务包括:中文分词、词性标注、NER、句法分析、指代消解、语义Parser等,这类任务一般并不解决应用中的实际需求,大多数是作为那些解决实际需求任务的中间阶段或者辅助阶段存在的。自从Bert/GPT出现之后,其实就没有必要做这些中间任务了,因为通过大量数据的预训练,Bert/GPT已经把这些中间任务作为语言学特征,吸收到了Transformer的参数里,此时我们完全可以端到端地直接解决那些最终任务,而无须对这种中间过程专门建模。
    2. 不同研究方向技术路线的统一。 可以分为两大不同类型的任务:自然语言理解类任务和自然语言生成类任务,自从Bert/GPT模型诞生后,出现了明显的技术统一趋向。首先,NLP中不同的子领域,其特征抽取器都逐渐从LSTM/CNN统一到Transformer上。其次,大多数NLP子领域的研发模式切换到了两阶段模式:模型预训练阶段+应用微调(Fine-tuning)或应用Zero/Few Shot Prompt模式。
  3. 从预训练模型走向通用人工智能。 在预训练模型发展的早期,技术框架收敛到了Bert模式和GPT模式这两种不同的技术范型,而且人们普遍更看好Bert模式一些,但是,随着技术的继续发展,你会发现,目前规模最大的LLM模型,几乎清一色都是类似GPT 3.0这种“自回归语言模型+Prompting”模式。为什么会这样呢?背后一定有其必然性,我认为可能主要源于两个原因。
    1. 把自然语言理解问题转换成让LLM模型生成对应xx的字符串,这样理解和生成任务在表现形式就实现了完全的统一。这说明自然语言生成任务,在表现形式上可以兼容自然语言理解任务,若反过来,则很难做到这一点。这样的好处是:同一个LLM生成模型,可以解决几乎所有NLP问题。
    2. 如果想要以零示例提示语(zero shot prompting)或少数示例提示语(few shot prompting)的方式做好任务,则必须要采取GPT模式。但是问题来了:为什么我们要追求zero shot/few shot prompting这种方式来做任务呢?

什么样的LLM模型,对我们是最理想的?

  1. 首先,LLM应该具备强大的自主学习能力。假设我们把世界上能获得的所有文本或者图片等不同类型的数据喂给它,它应该能够自动从中学习到里面包含的所有知识点,学习过程不需要人的介入,并且能灵活应用所学知识,来解决实际问题。因为数据是海量的,要吸收所有知识,就要非常多的模型参数来存储知识,所以这个模型必然会是一个巨无霸模型。
  2. 其次,LLM应该能解决NLP任何子领域的问题,而不仅支持有限领域,甚至它应该可以响应NLP之外其它领域的问题,最好是任意领域的问题都能得到很好地回答。
  3. 再者,当我们使用LLM解决某个具体领域问题的时候,应该用我们人类习惯的表达方式,就是说LLM应该理解人类的命令。这体现出让LLM适配人,而不是反过来,让人去适配LLM模型。人适配LLM的典型例子,比如绞尽脑汁去尝试各种不同的prompt,以试图找到好的提示语,才能很好地解决手头问题。

为什么我们要追求zero shot/few shot prompting这种方式来做任务呢?有两个原因。

  1. 第一,这个LLM模型规模必然非常巨大,有能力作出这个模型,或改动这个模型参数的机构必然很少。而任务需求方是千千万万的中小机构甚至是个人,就算你把模型开源出来,他们也无力部署这个模型,更不用说再用Fine-tuning这种模式去修改模型参数了。所以,我们应该追求不修正模型参数,就能让任务需求方完成任务的方式,也就是应该采取prompt模式完成任务,而非Fine-tuning模式。
  2. zero shot prompting也好,few shot prompting也好,甚至促进LLM推理能力的思维链(CoT,Chain of Thought)Prompting也好,就是上图中接口层中的现有技术。具体而言,zero shot prompting的初衷,其实就是人类和LLM的理想接口,直接用人类所习惯的任务表述方式让LLM做事情,但是发现LLM并不能很好地理解,效果也不好。经过继续研究,转而发现:对于某项任务,如果给LLM几个示例,用这些示例来代表任务描述,效果会比zero shot prompting好,于是大家都去研究更好的few shot prompting技术。可以理解为,本来我们希望LLM能够用人类常用的命令方式来执行某个任务,但是目前技术还做不到,所以退而求其次,用这些替代技术来表达人类的任务需求。如果理解了上述逻辑,很容易得出如下结论:few shot prompting(也被称为In Context Learning)只是一种过渡时期的技术。如果我们能够更自然地去描述一个任务,而且LLM可以理解,那么,我们肯定会毫不犹豫地抛弃这些过渡期的技术,原因很明显,用这些方法来描述任务需求,并不符合人类的使用习惯。

ChatGPT向GPT 3.5模型注入新知识了吗?应该是注入了,这些知识就包含在几万人工标注数据里,不过注入的不是世界知识,而是人类偏好知识。所谓“人类偏好”,包含几方面的含义:首先,是人类表达一个任务的习惯说法。比如,人习惯说:“把下面句子从中文翻译成英文”,以此表达一个“机器翻译”的需求,但是LLM又不是人,它怎么会理解这句话到底是什么意思呢?你得想办法让LLM理解这句命令的含义,并正确执行。所以,ChatGPT通过人工标注数据,向GPT 3.5注入了这类知识,方便LLM理解人的命令,这是它“善解人意”的关键。其次,对于什么是好的回答,什么是不好的回答,人类有自己的标准,例如比较详细的回答是好的,带有歧视内容的回答是不好的,诸如此类。这是人类自身对回答质量好坏的偏好。人通过Reward Model反馈给LLM的数据里,包含这类信息。总体而言,ChatGPT把人类偏好知识注入GPT 3.5,以此来获得一个听得懂人话、也比较礼貌的LLM。

可以看出,ChatGPT的最大贡献在于:基本实现了理想LLM的接口层,让LLM适配人的习惯命令表达方式,而不是反过来让人去适配LLM,绞尽脑汁地想出一个能Work的命令(这就是instruct技术出来之前,prompt技术在做的事情),而这增加了LLM的易用性和用户体验。是InstructGPT/ChatGPT首先意识到这个问题,并给出了很好的解决方案,这也是它最大的技术贡献。相对之前的few shot prompting,它是一种更符合人类表达习惯的人和LLM进行交互的人机接口技术。

同时,ChatGPT证明了我们现在是可以直接去追求理想LLM模型的,那么,未来的技术发展趋势应该是:追求规模越来越大的LLM模型,通过增加预训练数据的多样性,来涵盖越来越多的领域,LLM自主从领域数据中通过预训练过程学习领域知识,随着模型规模不断增大,很多问题随之得到解决。研究重心会投入到如何构建这个理想LLM模型,而非去解决某个领域的具体问题。这样,越来越多NLP的子领域会被纳入LLM的技术体系,进而逐步消失。我认为,判断某个具体领域是否该立即停止独立研究,其判断标准可采取以下两种方法,占其一即可:

  1. 判断某个任务,是否LLM的研究效果超过人类表现,对于那些LLM效果超过人类的研究领域,已无独立研究的必要。举个例子,GLUE与SuperGLUE测试集合里的很多任务,目前LLM效果已超过人类表现,与这个数据集合密切相关的研究领域,其实就没有继续独立存在的必要。
  2. 对比两种模式的任务效果,第一种模式是用较大的领域专用数据进行Fine-tuning,第二种是few-shot prompting或instruct-based方法。如果第二种方法效果达到或超过第一种方法,则意味着这个领域没有继续独立存在的必要性。如果用这个标准来看,其实很多研究领域,目前fine-tuning效果还是占优的(因为这种模式领域训练数据量大),看似还可独立存在。但是考虑到很多任务随着模型规模增大,few shot prompting效果持续增长,随着更大模型的出现,这个拐点很可能短期就会达到。

张俊林: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模型学会。或者说,如果想学会这类知识点,则需要让模型见到更大量的数据,以增加这些知识点在学习过程中必要的反向传播修正参数的机会

人机接口:从In Context Learning到Instruct理解。 一般我们经常提到的人和LLM的接口技术包括:zero shot prompting、few shot prompting、In Context Learning,以及Instruct。这些其实都是表达某个具体任务的描述方式。不过如果你看文献,会发现叫法比较乱。

  1. 其中Instruct 是ChatGPT的接口方式,就是说人以自然语言给出任务的描述,比如“把这个句子从中文翻译成英文”,类似这种。zero shot prompting我理解其实就是现在的Instruct的早期叫法,以前大家习惯叫zero shot,现在很多改成叫Instruct。尽管是一个内涵,但是具体做法是两种做法。早期大家做zero shot prompting,实际上就是不知道怎么表达一个任务才好,于是就换不同的单词或者句子,反复在尝试好的任务表达方式,这种做法目前已经被证明是在拟合训练数据的分布,其实没啥意思。目前Instruct的做法则是给定命令表述语句,试图让LLM理解它。所以尽管表面都是任务的表述,但是思路是不同的。
  2. 而In Context Learning和few shot prompting意思类似,就是给LLM几个示例作为范本,然后让LLM解决新问题。我个人认为In Context Learning也可以理解为某项任务的描述,只是Instruct是一种抽象的描述方式,In Context Learning是一种例子示范的例子说明法。

In Context Learning是个很神奇的技术。它神奇在哪里呢?神奇在你提供给LLM几个样本示例 $<x_1,y_1>,<x_2,y_2>,…<x_n,y_n>$,然后给它$x_{n+1}$LLM竟然能够成功预测对应的$y_{n+1}$,听到这你会反问:这有什么神奇的呢?Fine-tuning不就是这样工作的吗?你要这么问的话,说明你对这个问题想得还不够深入。Fine-tuning和In Context Learning表面看似都提供了一些例子给LLM,但两者有质的不同(参考上图示意):Fine-tuning拿这些例子当作训练数据,利用反向传播去修正LLM的模型参数,而修正模型参数这个动作,确实体现了LLM从这些例子学习的过程。但是,In Context Learning只是拿出例子让LLM看了一眼,并没有根据例子,用反向传播去修正LLM模型参数的动作,就要求它去预测新例子。既然没有修正模型参数,这意味着貌似LLM并未经历一个学习过程,如果没有经历学习过程,那它为何能够做到仅看一眼,就能预测对新例子呢?这正是In Context Learning的神奇之处。

未来

关于大模型的观点、预言和碎碎念

  1. 目前大模型的网络结构是否还可以优化?目前的结构基本都是decoder-only或者encoder-decoder架构,是否还有其他的可能性?
  2. 目前用于构建语言模型骨架的Transformer layer是否是最佳的结构?
  3. 大模型训练时普遍会遇到训练不稳定的问题,大模型训练不稳定的原因是什么?能不能通过改进模型结构或参数初始化之类的方法以解决?
  4. 大模型如何扩展到更多的模态?如何设计支持不同模态的训练目标?如何设计支持不同模态的模型结构?
  5. 如何更有效的将大模型蒸馏到小模型?如何将多模态大模型蒸馏到单一模态的小模型?(用于支持某个具体的业务场景)
  6. 自回归形式的解码普遍较慢,如何设计更快的解码方法支持未来LLM的大规模应用?
  7. 如何在不更新参数的情况下为大模型插入最新的世界知识?
  8. 如何从各个维度客观评估目前大模型的效果和能力边界?
  9. 如何让大模型准确完成一些没有确定步骤的工作,比如规划并安排一次旅行。

对于工业界大模型的一些看法

  1. 大模型创业公司死路一条。为了训练一个效果优异的大模型,需要长期且海量的人力和算力投入,创业公司耗不起,投资人更等不起,尤其是已经有了一个OpenAI的情况下。对与第三方来说,如果同样是调API,为什么不用OpenAI的而要用你的呢?
  2. 训练一个千亿级别的大模型并没有非常难,难的是训练一个效果好的大模型。事实上,这两年有许多国产大模型问世,学术界有清华CPM,GLM,智源的悟道等,工业界有华为的盘古(这里特别表扬下华为,盘古模型是很早就开始的一个项目,对于大模型的研发也一直有很多的投入,比知乎上天天只会在那里说怪话神神不知道高到哪里去了),阿里的M6,百度文心。然而,这些模型都跟GPT-3有着明显的差距。差距的产生可能源于语料的丰富程度,也有可能源于训练时加入的一些魔法tricks。由于OpenAI不再公布训练细节,因此OpenAI曾经踩过的坑,现在需要国内各个大模型团队重新踩一遍了。而每一次的训练,都是经费的燃烧。(就这还不一定踩的上。)
  3. 由于2的原因,人工智能的研究会迅速走向封闭。
  4. 由于2和3的原因,人工智能的研发人员将变成公司最宝贵,也是最私密的财产,任何一个研发人员的流失都意味着公司之前燃烧大量经费才得到的实验结论、经验和模型改进方法拱手送给竞争对手。
  5. 国内互联网公司对于大模型的重视程度远远不够。大模型的研发就像芯片行业,是个winner takes all的行业。谁先形成“巨额研发成本-产品-销售收入反哺研发”的正向循环,谁就能对追赶者建立行业壁垒。而目前国内工业界对大模型研发有较多投入的也只有华为和百度两家,而其他的巨头靠着游戏、外卖、电商赚钱太久了,缺少对新技术的敏感性。

朱啸虎:不要追逐大模型,要跟着大模型进化

  1. 大模型最可怕的地方,在于迭代的速度很快。去年发布了3.5,今年出来了4,关键看明年的5。如果ChatGPT5出来,真的是个颠覆性的变化,可以很多场景下达到商业化的质量。大模型已经出来好几年了,以前大家都不敢投,不敢相信会出奇迹。微软砸几十亿美金都是“毛毛雨”,它敢砸这个钱,中国的大厂在过去几年市值掉得比较厉害,在没有看到曙光之前不敢砸钱。这就是为什么美国先出来了大模型的原因,就是大力出奇迹,砸钱砸GPT去训练。但一旦有人把路走通以后,后面跟的人就很容易了,而且也不需要这么多钱。
  2. 今天AIGC还有很多问题,比如幻觉。你要一个高准确度的场景,是不可行的,比如金融、法律、医疗,用大模型做肯定有问题。比如编程。ChatGPT4只能提升50%的效果,只能减少初级程序员,它编出来的代码有问题,需要更多的资深程序员去改。等到ChatGPT5出来,能提升90%的效果,连资深程序员都不需要了。有一个做职业教育的公司,自己训练了一个大模型,取代了公司销售。他们靠公司社群营销,之前有数百人做社群营销,现在用AI,转化率比人工翻了1-3倍。ChatGPT3在3.5水平,就能做到这么多,如果是ChatGPT4的水平,能翻5倍以上。

AI和互联网最大的区别是,互联网越过0分就具有了实用价值,而AI不到60分价值就是0。因为互联网替代的对象之前几乎不存在,或者成本极其高昂(海底光缆之前跨大洲的数据通信),很容易就落地。但AI的替代对象就是人,或者现有软件,而这些的成本和效率之间的平衡,已经被当今世界优化到了极致。因此AI的价值拐点,本质上是AI越过社会智力成本的拐点,一旦越过,AI价值的确是非线性上升。目前的GPT-4的水平,只是到了“解决某一项任务”的水平,还不能“替代某一项工作”。因为任何一项人类工作都是非常多“任务项”组成的,一项任务的解决无法撑起一个工种。但正如上图所示,人类工作种类是分层的,随着AI能力一步步爬升,是对一项项任务、最终是一个个工作类别的持续替代。AI进步慢,替代就慢,AI进步快出现跃升(如到了AGI),替代会猛然加速。这可能就是未来5年的叙事。

其它

ChatGPT如何成了学习的神兵利器

通俗解构语言大模型的工作原理当LLM“阅读”一篇短篇小说时,它似乎会记住关于故事角色的各种信息:性别和年龄、与其他角色的关系、过去和当前的位置、个性和目标等等。研究人员并不完全了解LLM是如何跟踪这些信息的,但从逻辑上讲,模型在各层之间传递时信息时必须通过修改隐藏状态向量来实现。现代LLM中的向量维度极为庞大,这有利于表达更丰富的语义信息。例如,GPT-3最强大的版本使用有12288个维度的词向量,也就是说,每个词由一个包含12288个的数字列表表示。这比Google在2013年提出的word2vec方案要大20倍。你可以把所有这些额外的维度看作是GPT-3可以用来记录每个词的上下文的一种“暂存空间(scratch space)”。较早层所做的信息笔记可以被后来的层读取和修改,使模型逐渐加深对整篇文章的理解。因此,假设我们将上面的图表改为,描述一个96层的语言模型来解读一个1000字的故事。第60层可能包括一个用于约翰(John)的向量,带有一个表示为“(主角,男性,嫁给谢丽尔,唐纳德的表弟,来自明尼苏达州,目前在博伊西,试图找到他丢失的钱包)”的括号注释。同样,所有这些事实(可能还有更多)都会以一个包含12288个数字列表的形式编码,这些数字对应于词John。或者,该故事中的某些信息可能会编码在12288维的向量中,用于谢丽尔、唐纳德、博伊西、钱包或其他词。这样做的目标是,让网络的第96层和最后一层输出一个包含所有必要信息的隐藏状态,以预测下一个单词。Transformer在更新输入段落的每个单词的隐藏状态时有两个处理过程:

  1. 在注意力步骤中,词汇会“观察周围”以查找具有相关背景并彼此共享信息的其他词。
  2. 在前馈步骤中,每个词会“思考”之前注意力步骤中收集到的信息,并尝试预测下一个单词。在注意力头在词向量之间传输信息后,在这个阶段单词之间没有交换信息,前馈层会独立地分析每个单词。前馈层之所以强大,是因为它有大量的连接。

在论文 BERTnesia: Investigating the capture and forgetting of knowledge in BERT 的结论中也能看出,不同的知识在 Transformer 的存储是存在分层特点的,这与我们在视觉预训练模型学到的人脸识别算法的分层特点很像。

语言本身是可预测的。语言的规律性通常(尽管并不总是这样)与物质世界的规律性相联系。因此,当语言模型学习单词之间的关系时,通常也在隐含地学习这个世界存在的关系。预测可能是生物智能以及人工智能的基础。如果我们提供足够的数据和计算能力,语言模型能够通过找出最佳的下一个词的预测来学习人类语言的运作方式。不足之处在于,最终得到的系统内部运作方式人类还并不能完全理解。

Aidan Gomez:说到Transformer以及这一代语言模型,我们能够看到很多功能强大的应用,比如GPT-3、Cohere以及ChatGPT等。它们的基本原则是,通过扩展模型实现对更复杂数据集的建模,显然,最复杂的数据集应该是互联网数据之类的数据,这类大型文本语料库已经积累了几十年,目前,互联网使用人数占到全球总人数的百分之六七十,人们在线上进行各类活动,如开办编程课程、语言课程,并谈论各种事件、问题等等。如果要对这个大型、高度多样化的数据集建模,我们需要用到极其复杂的模型,而这正是Transformer的用处所在。Transformer是一种神经网络架构,这种结构非常擅长扩展,并且可以有效地进行并行化处理,这在拥有成千上万个GPU加速器的大型超级计算机上进行训练非常重要。扩展模型和数据集带来了极好的成效,正如OpenAI所说:Transformer模型成为了多任务处理大师。这意味着,相同的模型、同一组权重能够完成多种任务,包括翻译、实体抽取、撰写博客和文章等等。现在,我们创建出了能够通过交流让其完成任务的模型(Cohere称之为命令模型,OpenAI称之为指令模型),语言大模型技术已经走进人们生活,变得更加直观可用。如今,在多数人眼中,我们可以向语言大模型下达自然语言指令,然后模型会按照指令生成相应的结果。

  1. 如果最初的原始模型拥有来自网页的万亿级单词,那么在微调阶段,需要的数据数量级要小很多,重要的是这一阶段的数据要体现我们对模型行为的期望。以命令模型(与OpenAI的指令模型类似)为例,我们希望给模型下达一些自然语言指令,然后模型能以直观正确的方式做出响应,比如让模型以兴奋的语调编辑一篇博客文章。为了达成上述目标,需要收集语气兴奋的博客文章,将它们放入数据集,用这些数据对模型进行微调,这样就能将知识渊博的大型模型引向可直观控制的模型。
  2. 与ChatGPT或对话模型类似,面对知识渊博且功能强大的模型,我们可用小型精细化的数据集对其进行微调,将模型引向我们所希望的发展方向,如果想要一个对话模型,就需要向模型展示大量对话,模型会根据我们展示的数据集进行调整。