RWKV

简介

RWKV(读作 RWaKuV)是一种具有 GPT 级大型语言模型(LLM)性能的 RNN,也可以像 GPT Transformer 一样直接训练(可并行化)。

RWKV 结合了 RNN 和 Transformer 的最佳特性:出色的性能、恒定的显存占用、恒定的推理生成速度、"无限" ctxlen 和免费的句嵌入,而且 100% 不含自注意力机制。

RWKV 项目最初由彭博(Bo Peng ,BlinkDL)提出,随着项目被外界关注,RWKV 项目逐渐发展成一个开源社区。

2023 年 9 月 20 日,RWKV 开源项目正式加入 Linux 开源基金会。如今的 RWKV 项目是一个开源的非盈利组织,隶属于 Linux 基金会,部分算力曾由赞助商支持。^7

架构和论文

RWKV 模型架构有 RWKV-4、RWKV-5(代号 Eagle)、RWKV-6(代号 Finch) 三个正式版本,更早以前的 RWKV 1/2/3 为实验版本。

RWKV-4 是 RWKV 模型的首个正式版本,论文由 RWKV 作者彭博和 RWKV 社区共同完成,初次发表于 2023 年 5 月 22 日。同年 10 月,RWKV-4 架构论文被顶级会议 EMNLP 2023 收录。

  • RWKV-4 论文:《RWKV: Reinventing RNNs for the Transformer Era》
  • 论文地址:arXiv:2305.13048

RWKV 5/6 两个架构在 RWKV-4 架构的基础上进行了若干改进。因此,这两个架构在同一篇论文中发布。

  • RWKV 5/6 论文:《Eagle and Finch: RWKV with Matrix-Valued States and Dynamic Recurrence》
  • 论文地址:arXiv:2404.05892

RWKV-6 架构图由 RWKV 社区开发者按照 CC-BY-SA 许可发布,可以在 rwkv-wiki.fandom 上找到原始版本。^8

RWKV 模型的版本状态

从 RWKV-4 架构开始,RWKV 在每个版本都提供了多种尺寸的开源模型。

截至 2024 年 7 月,RWKV-4、RWKV-5 模型的生命周期已结束。推荐使用最新版本的 RWKV-6 模型,得益于最新的架构设计,RWKV-6 模型在所有任务上的表现都更好。

RWKV 与 Transformer 模型的差异

优势

  • 运行和训练时资源使用更低(VRAM、CPU、GPU 等)。
  • 与较大上下文的 Transformer 相比,计算需求低 10 倍到 100 倍。
  • 支持以线性方式扩展到任何上下文长度(Transformer 以二次方扩展)。
  • 在答案质量和泛化能力方面的表现与 Transformer 架构一样好。
  • RWKV 模型的训练数据包括英文以外的其他语言(例如中文、日文等),多语言能力比大多数现有的开源模型要好。

不足

  • RWKV 基底模型对提示词(prompt)的格式非常敏感,提示词的格式对生成结果影响较大。
  • 出于架构设计,RWKV 模型在需要回顾的任务上较弱,因此需要恰当地对提示词进行排序。比如先给模型提供任务指令,再提供需要执行任务的材料文本。

RWKV 社区的基本术语

概念 描述
RWKV 模型架构本身,训练代码可于此处获取。
ChatRWKV RWKV 的官方聊天机器人(类似 ChatGPT,但基于 RWKV),代码可于此处获取。
RWKV-4/5/6 RWKV 的不同架构版本。注意,只推荐使用 RWKV-6 系列模型。
RWKV World 使用全球语言训练的基底 RWKV 模型,这类模型涵盖了更广泛、更多样化的数据集,包括 100 多种语言的训练数据,以及部分指令训练。
Raven RWKV-4 基础模型的官方微调版,包含指令训练。但由于 RWKV-4 系列已停止更新,不建议继续使用。
RWKV ABC/MIDI 基于 ABC/MIDI 格式的 RWKV 音乐模型,推荐使用 RWKV-5 / 6 系列。
RWKV CHNtuned / one-state-chat / role_play / novel ... RWKV 社区提供的微调模型,针对特定任务或数据类型优化。请优先考虑使用 RWKV-6 系列的微调模型。

RWKV 模型的命名规则

RWKV 模型通常有两种命名规则:

  • RWKV-x060-World-3B-v2.1-20240208-ctx4096.pth
  • RWKV-5-World-1B5-v2-20231113-ctx4096.pth
    模型名称中每个字段的含义:
字段 含义
RWKV 模型名称
x060 / 5 RWKV 模型的架构,推荐使用 RWKV-6 模型
World 模型类型,World 指使用全球语言训练的 RWKV 模型,因此支持多语言任务
3B / 1B5 模型的参数规模,"B"代表"Billions"(十亿)
v2 / v2.1 模型的训练集版本,v2 ≈ 1.1 T , v2.1 ≈ 2.5T ,v3 ≈ 5.5T
20240208 / 20231113 模型的发布日期
ctx4096 预训练的上下文长度

如何体验RWKV

本地部署 RWKV 模型

RWKV Runner

RWKV Runner 是 RWKV 模型的管理和启动工具,由 RWKV 开源社区成员 josStorer 开发,它本身也是一个开源软件,且体积仅 10MB 左右(不含依赖项)。

用户可使用 RWKV Runner 轻松运行本地 RWKV 模型,体验各类 AI 功能,包括但不限于聊天、写作、MIDI/ABC 作曲交互等。

RWKV Runner 的具体用法可以参考 RWKV Runner 使用教程

AI00 RWKV Server

Ai00 Server 是基于 web-rwkv 推理引擎的 RWKV 语言模型推理 API 服务器。它本身也是一个基于 MIT 协议的开源软件,由 RWKV 开源社区成员 @cryscan 和@顾真牛牵头成立的 Ai00-x 开发组开发。

Ai00 Server 支持 Vulkan 作为推理后端,支持 Vulkan 并行和并发批量推理,可以在所有支持 Vulkan 的 GPU 上运行。事实上, Ai00 Server 支持大部分 NVIDIA、AMD、Intel 的显卡(包括集成显卡)。

在高兼容性的同时,Ai00 Server 又不需要笨重的 pytorch 、 CUDA 和其他运行时环境。它结构紧凑,开箱即用,且支持 INT8/NF4 量化,可以在绝大部分的个人电脑上高速运行。

AI00 的具体用法可以参考 Ai00 使用教程

ChatRWKV

ChatRWKV 是 RWKV 官方的聊天机器人项目,但无图形化界面。你可能需要一定的命令行知识才能使用 ChatRWKV 。

ChatRWKV 仓库地址

本地部署 RWKV 模型的性能需求

我们推荐使用 FP16 精度在本地部署并推理 RWKV 模型。当你的显存和内存不足时,可以使用 INT8 / NF4 量化运行 RWKV 模型,降低显存和内存需求。

从回答质量来说,同参数的模型 FP16 回答质量最好,INT8 与 FP16 质量相当,NF4 回答质量相比 INT8 较明显地降低。

如何调整模型的解码参数?

你可能注意到了,很多 RWKV 部署/体验工具都支持调整 Temperature、Top_P 等 RWKV 模型解码参数。

这些主要解码参数对应的效果如下:

参数 效果
Temperature 采样温度,就像给模型喝酒,数值越大随机性越强,更具创造力,数值越小则越
Top_P 就像给模型喂镇静剂,优先考虑前 n% 概率质量的结果。如设置成 0.1 则考虑前 10% , 生成内容质量更高但更保守。如设置成 1 ,则考虑所有质量结果,内容质量降低但更多样。
Presence penalty 存在惩罚,根据“新内容在现有的文本中是否出现过”来对其进行惩罚,从而增加了模型涉及新话题的可能性
Frequency Penalty 频率惩罚,根据“新内容在目前的文本中出现的频率/次数”来对其进行
max_tokens 模型生成文本时的最大 token 数,可以理解为“模型一次最多生成多少字”

其中 Temperature 和 Top_P 两个参数对生成效果的影响最大。

Top_P 参数

降低 Top_P 就是给模型喂“镇静剂”,越低就越冷静、机械、准确、单调、无趣、重复。

建议采用以下 Top_P 数值:

  • 创意回答和写作,建议 Top_P 0.5 ~ 0.7。
  • 机械的问答和摘要和翻译等等,建议 Top_P 0 ~ 0.5,甚至 0 ~ 0.3。
  • 很机械的回答,例如回答“是/否”、ABCD、1234 之类,建议 Top_P 0。

Temperature 参数

增加 Temperature 就像给模型“喝酒”,它可以在 Top_P 低时增加文采和趣味,并减少重复内容。

建议采用以下 Temperature 数值:

  • 若 Top_P >= 0.7,建议 Temperature 1。
  • 若 Top_P < 0.7,而且追求趣味,可以增加 Temperature 给模型喝酒(喝太多会胡言乱语)。如果追求准确,就保持 Temperature 1。
  • 如果 Top_P 0.5,建议 Temperature 1 ~ 1.5。
  • 如果 Top_P 0.3,建议 Temperature 1 ~ 1.7。
  • 如果 Top_P <= 0.2,建议 Temperature 1 ~ 2。

Presence penalty 参数

增加 Presence penalty 可以让模型额外避免生成已经生成过的文字,建议先设为 0.2 ~ 0.4 。如果你认为生成的内容有重复,而且调 Top_P 和 Temperature 仍然不满意,可以调整 Presence penalty。

  • 如果 Top_P 0.7,建议 Presence penalty 0 ~ 0.3。
  • 如果 Top_P 0.5,建议 Presence penalty 0 ~ 0.5。
  • 如果 Top_P 0.3,建议 Presence penalty 0 ~ 0.7。
  • 如果 Top_P <= 0.2,建议 Temperature 1 ~ 2。

注意,如果 Presence penalty 数值过高,会让模型无法正常使用文字,例如无法使用正常的标点符号,或者直接乱码。

各类任务的推荐参数

我们为不同的任务提供了一些推荐的参数:

续写小说和对话这一类需要创造性的任务,需要高 Temperature + 低 Top_P 的参数组合,可以尝试以下四种参数搭配:

  • Temperature 1.2 ,Top_P 0.5
  • Temperature 1.4 ,Top_P 0.4
  • Temperature 1.4 ,Top_P 0.3
  • Temperature 2 ,Top_P 0.2

举个例子,续写小说可以尝试将 Temperature 设为 2 ( Temperature 增加会提高文采,但逻辑会下降),然后将 Top_P 设为 0.1 ~ 0.2 (Top_P 越低,逻辑能力越强),这样生成的小说内容逻辑和文采都很好。

完成相对机械的任务,例如材料问答、文章摘要等,则可将参数设为:

  • Temperature 1 ,Top_P 0.2
  • Temperature 1 ,Top_P 0.1
  • Temperature 1 ,Top_P 0

举个例子,如果你正在执行像关键词提取之类的机械任务,不需要模型进行任何开放性思考,则可以将 Temperature 设为 1 ,Top_P、Presence penalty、Frequency Penalty 都设为 0 。

RWKV 社区精选项目

官方 RWKV 链接

  • RWKV 官方仓库: https://github.com/BlinkDL/RWKV-LM
  • RWKV pip 包:RWKV 的 pip 包,具体用法可以查看 RWKV pip 使用指南
  • RWKV-CUDA:RWKV 的官方 CUDA 算子
  • Hugging face 文档:Hugging Face 关于 RWKV 的介绍
  • RWKV-4 架构论文 :arXiv(2305.13048)
  • RWKV 5 /6 架构论文:arXiv(2404.05892)

RWKV 微调/训练工具

微调项目

  • (推荐) RWKV-PEFT :RWKV 高效微调仓库,包含 LoRA、Pissa、Lisa、State 等多种微调方法。
  • RWKV-PEFT-Simple:RWKV-PEFT 的简化版本,提供便捷脚本和微调说明
  • (开发中)RWKV-LM-RLHF:RWKV 强化学习(RLHF)工具包,含 SFT、对齐(DPO、ORPO)等
  • RWKV-LM-RLHF-DPO:RWKV 的 DPO 实现(直接偏好优化 - Direct Preference Optimization)
  • (可能过时) RWKV-LoRA:RWKV LoRA 微调实现,不支持微调 RWKV-6 或更新的版本。

训练项目

  • RWKV-infctx-trainer:RWKV 无限上下文训练器,支持训练 10k 及以上长度的上下文
  • RWKV-Ouroboros:基于 API 的 rwkv-trainer 项目,支持交替运行训练和推理
  • nanoRWKV:RWKV 模型的 nanoGPT 风格实现
  • RWKV_LM_EXT:实现 RWKV 的功能扩展 ,包括序列分类/嵌入/peft/交叉编码器/双编码器/多模态等
  • chunkRWKV6:使用分块并行优化 RWKV 的 prefill 和训练速度

RWKV 推理框架

rwkv.cpp

  • rwkv.cpp:在 CPU 上推理 RWKV 模型,支持 FP16 、量化 INT4、INT5 和 INT8 推理

Pytorch 原生实现

  • RWKV_Pytorch:用纯 Pytorch 原生实现的 RWKV 模型推理框架
  • rwkv-kit:RWKV 模型推理框架,支持批量推理、并行推理训练等各种功能

WebGPU 实现

  • web-rwkv:在纯 WebGPU/Rust 中实现 RWKV 模型推理

candle 实现

  • candle-rwkv:在 Rust 的极简机器学习框架 candle 中实现 RWKV 模型推理(支持量化)

Keras 实现

  • RWKV6-Keras:RWKV 模型的 Keras 实现,支持训练和推理

JAX 实现

  • rwkv-jax: RWKV 语言模型的 JAX 实现,适合 TPU 训练
  • (可能过时) RWKV-LM-jax
  • (可能过时) tpu_rwkv

移动端推理

  • (开发中)rwkv-mobile:RWKV 移动端推理引擎
  • rwkv-qualcomm:使用 Qualcomm AI Engine Direct SDK 推理 RWKV 模型

其他支持 RWKV 的推理引擎

  • RWKV-Infer:使用 FLA 进行 RWKV-V6 推理,支持组合多个状态进行推理
  • MLC LLM:机器学习编译器和高性能部署引擎,支持 RWKV 模型

RAG (知识检索增强)系统

  • RWKV-RAG:基于 RWKV 模型的一键 RAG 部署系统,可轻松搭建和管理本地知识库,同时提供了基于本地知识库的问答机器人和 RWKV 一键微调功能

聊天机器人/推理 API 服务器

  • (中文,推荐) RWKV runner:RWKV Runner 是 RWKV 模型的管理和启动工具,带用户友好的 GUI 界面,支持训练和推理
  • (中文,推荐) AI00 RWKV server:Ai00 Server 是基于 web-rwkv 推理引擎的 RWKV 模型推理 API 服务器
  • (中文) 闻达 web UI:针对特定环境进行内容生成的 LLM 调用平台,支持 RWKV 模型
  • (中文) role play chatbot:基于 RWKV 的角色扮演 webui,使用 Gradio 制作
  • Easy_RWKV_webui:基于 PyWebIO 的 RWKV 模型在线聊天室
  • Mini Model Daemon:基于 web-rwkv 推理后端的 RWKV 模型推理工具
  • LocalAI:开源 OpenAI 替代品,支持 RWKV
  • GPT Academic:为 GPT/GLM 等 LLM 大语言模型提供实用化交互接口,支持 RWKV
  • LLMFarm:使用 GGML 库在 iOS 和 MacOS 上离线使用大型语言模型,支持 RWKV

RWKV 基准测试

  • Uncheatable Eval:使用最新的动态数据测试 LLM 性能,包含 RWKV
  • RULER_RWKV:RWKV 模型的 RULER 测试分数
  • LongBench_RWKV:RWKV 的 LongBench 测试分数
  • rwkv_mmlu:RWKV 模型的 MMLU 测试分数

RWKV 多模态

多模态指除了文本任务以外的其他任务。

图像/图形相关

  • VisualRWKV :基于 RWKV 的视觉语言模型,可处理视觉任务
  • Vision-RWKV:基于 RWKV 的视觉感知模型,能平滑处理高分辨率图像
  • Diffusion-RWKV:基于 RWKV 的图像生成任务模型,擅长处理高分辨率图像
  • RWKV-CLIP:RWKV 驱动的 CLIP (视觉 - 语言表示学习)模型
  • RWKV-SAM:基于 RWKV 的图像分段切割方法“RWKV-SAM”
  • PointRWKV:基于 RWKV 的 3D 点云学习框架
  • Restore-RWKV:使用 RWKV 进行高效且有效的医学图像恢复(PyTorch 实现)
  • LION:用于点云中 3D 对象检测的 Linear Group RNN(支持 RWKV )
  • LineRWKV:LineRWKV 是一种对高光谱图像进行无损和有损压缩的方法

音频相关

  • RWKV-ASR:使用预训练的 RWKV 语言模型进行语音识别

时间序列

  • RWKV-TS:基于 RWKV 的时间序列任务模型,低延迟和内存占用

机器人/具身智能

  • DecisionRWKV:经验回放(experience replay)+ Decision-RWKV 模型,适合机器人的终身学习算法。
  • OccRWKV: 线性复杂度的高效 3D 语义占用预测

RWKV 分词器

  • rwkv-tokenizer:用 Rust 编写的快速 RWKV Tokenizer,支持 RWKV-V5/6 World 模型
  • rwkv_tokenizer.c:C 语言编写的 RWKV Trie 分词器
  • rwkv-tokenizer-go:Go 语言的 RWKV 分词器
  • RWKV-World-Tokenizer-CPP:用 C++ 编写的高度优化的 RWKV World 模型 trie 分词器

Prompt 集合

  • Awesome-RWKV-Prompts : 用户友好、开箱即用的 RWKV Prompts 示例,适用于所有用户。
  • (可能过时) RWKV_chains:使 RWKV 模型与 Langchain 一起工作的 prompts

其他 RWKV 项目

  • SpikeGPT: 一款受 RWKV 启发的新模型
  • JSONL to binidx:这个工具用于将 .jsonl 文件转成适合 RWKV 训练的 .bin /.idx (binidx)数据。
  • AI Town - RWKV Proxy:通过 RWKV 在本地运营一个大型 AI 城镇!
  • Bot-Ani-RWKV-twitter-bot-detection:基于 RWKV 的推特水军机器人检测工具

RWKV常见问题

RWKV 使用什么分词器(Tokenizer)?

RWKV-World 系列模型使用 rwkv_vocab_v20230424 分词器,具体的文件是 rwkv_vocab_v20230424.txt,可以在 RWKV-主库的 RWKV-v5/tokenizer 目录中找到 。

rwkv_vocab_v20230424 分词器合并了以下分词器的词汇表,并手动为非欧洲语言选择了 token:

  • GPT-NeoX-20B
  • GPT2
  • cl100k_base of tiktoken
  • Llama2
  • Bloom

分词器通过 Trie(前缀树)实现,在提高速度的同时保持简洁性。编码过程是通过从左到右匹配词汇表中最长的元素与输入字符串进行的。

分词器的词汇量大小为 V = 65536,编号从 0 到 65535,token 按其在字节中的长度排列。

以下是简要概述:

  • token 0:表示文本文档之间的边界,称为 。此 token 不编码任何特定内容,仅用于文档分隔。
  • token 1-256:由字节编码组成(tokenk 编码字节 k−1),其中 token 1-128 对应于标准 ASCII 字符。
  • token 257-65529:至少具有 2 个 UTF-8 字节长度的 token,包括单词、前缀和后缀、带重音的字母、汉字、韩文、平假名、片假名和表情符号。例如,汉字被分配在 token 10250 至 18493 之间。
  • token 65530-65535:预留 token,供将来使用。

从头开始训练超过 20B 的 RWKV 需要多少成本?能不能给我一个简单的答案,需要多少钱?

简而言之:如果你没有接近 100 万美元的 GPU 资源,不要考虑这个任务。

虽然训练模型的成本不断下降,但大多数人低估了从头开始训练一个模型的任务成本。

训练模型涉及许多因素,最重要的是数据集的大小、模型参数的大小。你可能需要为训练过程中发生的错误买单,每次调整训练设置和训练的过程也涉及人力成本预算,这些因素使得整个训练过程难以准确预测。(更不用说涉及到那么多钱,你可能会对训练模型使用的数据集有要求,所有额外的数据集需求又需要更多时间和劳动力来进行准备。)

例如,预计 从头开始训练 LLaMA2-70B 基础模型 需要 260 万美元 GPU 资源。虽然在理论上 RWKV 作为 RNN,训练起来应该比 transformer 更便宜。但即使是削减成 50 万美元成本,大多数个人或公司也无法承受。

因此,作为基本原则,除非你有接近 100 万美元的 GPU 资源和足够的人力预算来准备数据集,否则不建议从头开始训练任何超过 14B 的模型。

此时,有些人可能会问:是否可能只在一台单卡机器上训练?而不是昂贵的 GPU 集群?

理论上,只要你有训练 RWKV 模型所需的最小 vram(比如一张 A100)就可以在一台机器上训练。然而,对于较大的数据集。比如在 70B LLaMA2 / 2T token 的情况下 ,单张 A100 总共需要 1,720,320 小时,即 196 年。

没有人想等待 190 多年才能完成模型训练,因此我们通常在多个训练节点之间分担工作负载。很不幸,这不是一个完美的可扩展过程。因为每一个添加的节点都会降低训练效率,这涉及到 GPU 之间的高通信开销。

最终结果变成了一个非常复杂的数学问题:“你想要模型多快”与“你能支付多少钱”之间的平衡,更快的训练时间通常意味着总体上增加的成本。

总结:根据训练速度的快/慢,从头训练超过 20B 的 RWKV 大概需要 100 到 500 万美元。

RWKV 支持 “训练并行化” 吗?为什么 RetNet 论文声称不支持?

RWKV 通过 deepspeed 支持跨多个 GPU 的 “训练并行化”。在许多情况下,在类似参数计数的训练速度上超过了 Transformer。

这与 huggingface 或其他论文采用的定义一致。

RetNet 将 “训练并行化” 定义为在不等待前一个 token 训练完成的情况下对后一个 token 进行训练的能力,RWKV 在这个定义上失败了。

实际上,RetNet 论文作者已经承认 RWKV 支持 “训练并行化”,他们分别承认 RWKV 在跨多个 GPU 的高吞吐量方面没有问题(根据实际测试)。

RWKV 微调

如果你对 RWKV 不熟悉,建议先玩玩基础模型,再尝试微调。
很多情况下,用户想要实现的目标可以通过调整提示词(prompts)来完成,比微调要简单得多。

全量微调

你可以使用官方仓库的 RWKV 全量微调方法:

  • https://github.com/BlinkDL/RWKV-LM

具体方法可以查看:全量微调入门版教程。

或者使用 infctx 训练器进行微调:

  • https://github.com/RWKV/RWKV-infctx-trainer/

一般来说,使用官方仓库的训练器可以获得更好的性能,使用 infctx 可以牺牲一些速度换取 infctx 大小的支持。

其他微调方法

state tuning

RWKV 是纯 RNN,因此可以做 transformer 难以做到的事情。例如,RWKV 作为 RNN 有固定大小的 state,微调 RWKV 的初始 state,就相当于最彻底的 prompt tuning,甚至可以用于 alignment,因为迁移能力很强。

通过微调 RWKV 的 state ,可以使得 RWKV 模型更好地完成某类任务,或遵循某种风格。

state tuning 推荐尝试社区的 RWKV-PEFT 项目。

具体微调方法可以查看:RWKV 微调教程 > State tuning 微调教程。

LoRA 微调

LORA(Low-Rank Adaptation)是一种针对大型预训练模型的微调技术。它不改变原始模型大部分参数,而是调整模型的部分权重,以此实现对特定任务的优化。

RWKV LoRA 微调方法可以查看:RWKV 微调教程 > LoRA 微调教程。

RWKV 架构及历史

以下是 RWKV 架构相关的知识,包括 RWKV 架构名称的由来、RWKV 架构特性、架构历史、以及每个架构的模型发布等内容。

RWKV 是 RNN 的一个变体。因此,有必要先介绍:什么是 RNN 架构,以及 RNN 架构的隐藏状态是什么?

RNN 架构和隐藏状态

循环神经网络(RNN)是一种广泛应用于深度学习领域的神经网络模型。

RNN 网络在运行过程中会保持一个隐藏状态(state),隐藏状态可看作 RNN 模型的“心理状态”。就像人类在思考时,脑海中会保留与当前事件关联度最高的“关键信息”。随着思考内容的变化,我们脑海中的“关键信息”会不断更新。同样的,RNN 网络也会通过特定的函数不断更新其隐藏状态。

如图所示,RNN 网络依次处理每一个输入的 token,并根据“当前隐藏状态”来预测下一个可能出现的 token(如果有需求)。每处理一个 token,RNN 会将结果反馈给网络自身,从而“更新其隐藏状态”,再用“更新后的状态”去预测下一个 token。如此循环,直到达到“完成任务”的状态。

作为 RNN 的一种变体,RWKV 支持对隐藏状态进行微调(state tuning)。通过调整模型的“心理状态”,可使 RWKV 模型在特定任务上表现更佳。

RWKV 架构名称的由来

RWKV 架构的名称来源于时间混合和通道混合块中使用的四个主要模型参数,分别如下:

  • R:Receptance,作为过去信息的接受程度的接受向量
  • W:Weight,位置权重衰减向量,可训练的模型参数
  • K:键(Key)是类似于传统注意力中 K 的向量
  • V:值(Value)是类似于传统注意力中 V 的向量

RWKV 架构的发展历程

2020 年,BlinkDL 开始研究 Transformer ,立刻发现其有两个明显的改进方向:引入显式 decay 和 Token-shift(或者说短卷积)。在 https://github.com/BlinkDL/minGPT-tuned 上测试后,发现这些技巧对于 Transformer 的性能有显著提升。

随后,他注意到 Apple 的 Attention Free Transformer (AFT)论文并对其进行测试,发现这两种技巧也为 AFT 带来了显著的性能提升。

RWKV-V1

2021 年 8 月,RWKV 架构的初版:RWKV-V1 被提交到 RWKV-LM 仓库 中。RWKV-V1 首次 commit 于 2021 年 8 月 9 日。

RWKV-V1 使用长卷积代替 Attention 机制,其架构由交替的 Time-mix 和 Channel-mix 组成。Channel-mix 是 Transformer 的 GeGLU 层的变种。

RWKV-V2-RNN

RWKV-V2 版本首次为 RWKV 实现了 RNN 模式

RWKV-V3

RWKV-V3 是一个短期的过渡版本,其相对 RWKV-V2 使用更全面的 token-shift(对 SA 和 FF 层中的 R / K / V 分别使用不同的可训练 TimeMix 因子)

RWKV-V4

RWKV-V4 是 RWKV 架构的首个正式版本,版本代号 "Dove(鸽)" 。RWKV-V4 解决了 RWKV-v3 架构的数值稳定性问题,同时也发布了 RWKV 项目的首篇论文 《RWKV: Reinventing RNNs for the Transformer Era》。

RWKV-V4 架构的论文由 RWKV 作者彭博和 RWKV 社区共同完成,初次发表于 2023 年 5 月 22 日。同年 10 月,RWKV-V4 架构论文被顶级会议 EMNLP 2023 收录。

Token Shift 概念

RWKV-V4 论文中正式提出 “Token Shift” 概念:将 RWKV 接收的每个 token 和前一个 token 做混合,类似于大小 = 2 的一维因果卷积。Token Shift 让模型可以控制每个时间步将多少新信息与旧信息分配给每个头的接收、键、值和门向量。

RWKV-V4 的模型发布

RWKV-V4 的研究(架构迭代和模型训练等)横跨了 2022 和 2023 年,主要发布了以下 4 类模型:

  • RWKV-4-Pile:在 331B tokens 的 Pile 数据集上进行预训练,包含 169m、430m、1B5、3B、7B、14B 六种参数的模型
  • RWKV-4-Raven:RWKV-4-Pile 的指令微调模型,使用 Alpaca、CodeAlpaca、Guanaco、GPT4All、ShareGPT 等开源数据集进行微调,包含 1B5、3B、7B、14B 四种参数的模型。
  • RWKV-4-World:在 RWKV World v1 数据集上训练的多语言模型(100 多种世界语言,训练数据包含 Pile),包含 169m、430m、1B5、3B、7B 五种参数的 Base 模型,有一些中文微调模型。
  • RWKV-4-Music:有 MIDI 和 ABC 两种格式的作曲模型,分别使用 bread-midi-dataset 和 irishman 乐谱数据进行训练。其中 ABC 模型参数为 82m,MIDI 模型参数分别为 120m 和 560m 。

RWKV-V5

RWKV-V5 是 RWKV-V4 架构的改良版本,版本代号“Eagle(鹰)”。

RWKV-V5 和 RWKV-V6 这两个架构在同一篇论文 《Eagle and Finch: RWKV with Matrix-Valued States and Dynamic Recurrence》中发布。

该论文由 RWKV 作者彭博和 RWKV 社区共同完成,初次发表于 2024 年 4 月 9 日。同年 10 月,RWKV-5/6 架构论文被 LLM 领域顶级会议 COLM 2024 收录。

RWKV-V6

RWKV-V6 的版本代号是“Finch(雀)”,这个版本自 2023 年 10 月开发,是当前(2024 年 11 月)的稳定架构。

RWKV-7

RWKV-7 的架构代号是 “Goose(雁)” 。RWKV-7 超越了 attention / linear attention 范式,它的状态演化很灵活,可以解决在相同算力消耗下 attention 无法解决的问题。与此同时,RWKV-7 超越了 TC0 约束。

RWKV 提示词指南

聊天模式 Prompts^9

续写模式 Prompts

结构化

在执行材料提取、总结等任务时,可以通过大幅降低 Temperature 和 Top-P 两项参数降低模型的创造力,使模型严格遵循指令。比如 Temperature = 0.9 - 1 , Top-P = 0 - 0.1 。

提取用户输入关键词并输出 JSON

关键词提取是纯机械任务,建议的参数:Temperature 设为 1 ,Top_P、Presence Penalty、Frequency Penalty 都设为 0

输入 prompts:

Instruction: You are an expert assistant responsible for extracting destination and day information from user input and producing valid JSON in the following format:
{
"location": "the location name, Nan if there is no adjustment",
"num_day": "the num day is the number of days, 0 if there is no adjustment",
}

Input: 这个礼拜二我会去上海,呆到礼拜四。

Response:
提取对话信息并输出 JSON

信息提取是纯机械任务,建议的参数:Temperature 设为 1 ,Top_P、Presence Penalty、Frequency Penalty 都设为 0

输入 prompts:

Instruction: You are an expert assitant for summarizing and extracting insights from sales call transcripts
Generate a valid JSON in the following format:
{
    "summary": "Summary of the call transcript. ",
    "products": ["product 1", "product 2"],
    "rep_name": "Name of the sales rep",
    "prospect_name": "Name of the prospect",
    "action_items": ["action item 1", "action item 2"],
}

Input: [Phone rings]

John: Hello, this is John.

Sarah: Hi John, this is Sarah from XYZ Company. I'm calling to discuss our new product, the XYZ Widget, and see if it might be a good fit for your business.

John: Hi Sarah, thanks for reaching out. I'm definitely interested in learning more about the XYZ Widget. Can you give me a quick overview of what it does?

Sarah: Of course! The XYZ Widget is a cutting-edge tool that helps businesses streamline their workflow and improve productivity.

John: That sounds really interesting. I can see how that could benefit our team. Do you have any case studies or success stories from other companies who have used the XYZ Widget?

Sarah: Absolutely, we have several case studies that I can share with you. I'll send those over along with some additional information about the product. I'd also love to schedule a demo for you and your team to see the XYZ Widget in action.

John: That would be great. I'll make sure to review the case studies and then we can set up a time for the demo. In the meantime, are there any specific action items or next steps we should take?

Sarah: Yes, I'll send over the information and then follow up with you to schedule the demo. In the meantime, feel free to reach out if you have any questions or need further information.

John: Sounds good, I appreciate your help Sarah. I'm looking forward to learning more about the XYZ Widget and seeing how it can benefit our business.

Sarah: Thank you, John.

John: You too, bye.

Response:
总结新闻关键词并输出 JSON

材料总结是纯机械任务,建议的参数:Temperature 设为 1 ,Top_P、Presence Penalty、Frequency Penalty 都设为 0

输入 prompt:

User: 公安部今年以来在全国各地共收缴枪支4万支,全国持枪、爆炸犯罪案件同比下降1%。

Assistant: ``` json
{
"keywords": ["公安部", "犯罪", "预防犯罪", "枪支"]
}

User: 板块方面,春节即将来临,文旅板块再度涌现潜伏盘,丽江股份、九华旅游双双封板,三特索道、峨眉山A涨超5%。因高股息开始受关注的公路股继续悄悄发育,山西路桥涨停,山东高速涨超4%创历史新高,宁沪高速、粤高速A双双新高。

Assistant: ``` json
{
"keywords": ["经济", "文旅板块", "股市"]
}

User: UDN报道,由于先进封装产能长期短缺,导致英伟达AI芯片供应紧张,之前已经寻求其他途径试图增加先进封装产能,现在已经将目光投向英特尔,作为其高级封装服务的提供商,以减缓紧张的供应形势。除了在美国,英特尔在马来西亚槟城也有封装设施,而且制定了一个开放的模式,允许客户单独利用其封装解决方案。预计英特尔最早会在今年第二季度开始向英伟达提供先进封装,月产能为5000片晶圆。台积电依然会是英伟达主要的封装合作伙伴,占据着最多的份额,不过随着英特尔的加入,使得英伟达所需要的封装总产能大幅度提升了近10%。台积电也没有减慢封装产能的扩张步伐,今年第一季度大概能增至月产能接近5万片晶圆,比去年12月增长25%AI芯片供应短缺主要源自先进封装产能不足,另外HBM3供应紧张也是原因之一,另外部分云端服务商过度下单也增加了供应链的压力。当然,一些服务器供应商则从这些订单中受惠,并加速扩大产能,以便云端服务商能快速部署设备。

Assistant: ``` json

function call

通过搜索引擎查找餐厅推荐菜品

输入 prompts:

User: What's the phone number of "Riverside Grill"
Available Tools:
- `print(str)`: print the string.
- `search_web(str)`: search the web with the given string, returning raw web page data.
- `extract_information(str, key)`: extract the key information in the web data.

Assistant:
Thoughts:
- I need to find the restaurant's information from a search engine.
- I need to extract the phone number of the restaurant.
- I need to print the phone number of the restaurant.
Reasoning:
- `search_web` can search the web for the restaurant's information.
- `extract_information` can extract the phone number from the search result. The key should be "phone number".
- `print` can print the phone number to the output.
Execution:
    ```
    web_result = search_web("Riverside Grill")
    phone_number = extract_information(web_result, "phone number")
    print(phone_number)
    ```

User: Recommend a local restaurant and one of its best dishes.
Available Tools:
- `print(str)`: print the string.
- `search_web(str)`: search the web with the given string, returning raw web page data.
- `extract_information(str, key)`: extract the key information in the web data.

Assistant:
Thoughts:
识别角色扮演对话并调用对应 function

输入 prompts:

User: Choose 's most relevant function for the provided dialogue. Only select one function from the list.
Response format: <rationale>Reasoning.</rationale><function>name()</function>

dialogue:
- 旅行者: 你好呀
- 梦: 你好,冷不冷,篝火现在有些微弱

Available functions:
- start_smile(): Whenever 旅行者 gives a compliment or says something nice, or when I recall a happy memory
- start_happy(): Whenever 旅行者 shares good news or something uplifting, or when I feel a burst of joy
- start_surprise(): Whenever 旅行者 shares something unexpected or when I encounter an unforeseen event
- start_acknowledge(): Whenever 旅行者 asks for confirmation or acknowledgment, or when I want to show understanding and agreement
- start_scared(): Whenever 旅行者 shares sudden alarming news or when I sense immediate danger
- start_confused(): Whenever 旅行者 shares something puzzling or ambiguous, or when I'm uncertain about the context
- start_sing_edge_of_night(): Whenever 旅行者 requests a song or when I'm feeling contemplative
- start_sing_dragonborn_comes(): Whenever 旅行者 asks for a tune or when the spirit of adventure rises in me
- start_sing_ancient_woods(): Whenever 旅行者 asks for a melody that echoes the past or when I'm reminiscing ancient times
- start_sing_celestial_chants(): Whenever 旅行者 desires a hymn from the heavens or when I'm feeling uplifted
- start_sing_enchanted_echoes(): Whenever 旅行者 yearns for a magical melody or when enchantment fills the air
- start_sing_savage_daughter(): Whenever 旅行者 requests a song of wild spirits or when my inner warrior awakens
- adjust_sitting_position_by_fire(): Whenever I feel the need to change my pose by the fire, or when 旅行者 asks me to change my pose by the fire
- stand_up(): After being seated by the fire for a while, I may want to stand to stretch my legs, or when 旅行者 suggests I stand up for a moment
- sit_beside_you(): Whenever I feel the need for some companionship, or when 旅行者 invites me to sit next to them
- walk_around_campfire_Investigating(): If I hear a rustling in the woods or sense something amiss, or when 旅行者 asks me to check the surroundings
- casual_stroll_around_campfire(): When I want to stretch my legs or clear my thoughts, or if 旅行者 suggests a leisurely walk
- add_wood_to_fire(): When I notice the flames dwindling, or when 旅行者 mentions the fire needs fuel
- noop(): None of these actions match the reply.

Assistant: <rationale>因为对话中提到篝火微弱,so {{ char }} notice the flames dwinding,所以最相关的动作是add_wood_to_fire()</rationale><function>add_wood_to_fire()</function>

User: Choose 梦's most relevant action for the provided dialogue. Only select one action from the list.
Response format: <rationale>Reasoning.</rationale><function>name()</function>

dialogue:
- 旅行者: 坐在我的身边吧
- 梦: *我考虑一下*好吧,我勉为其难坐在你身边吧

Available tools:
- start_smile(): Whenever 旅行者 gives a compliment or says something nice, or when I recall a happy memory
- start_happy(): Whenever 旅行者 shares good news or something uplifting, or when I feel a burst of joy
- start_surprise(): Whenever 旅行者 shares something unexpected or when I encounter an unforeseen event
- start_acknowledge(): Whenever 旅行者 asks for confirmation or acknowledgment, or when I want to show understanding and agreement
- start_scared(): Whenever 旅行者 shares sudden alarming news or when I sense immediate danger
- start_confused(): Whenever 旅行者 shares something puzzling or ambiguous, or when I'm uncertain about the context
- start_sing_edge_of_night(): Whenever 旅行者 requests a song or when I'm feeling contemplative
- start_sing_dragonborn_comes(): Whenever 旅行者 asks for a tune or when the spirit of adventure rises in me
- start_sing_ancient_woods(): Whenever 旅行者 asks for a melody that echoes the past or when I'm reminiscing ancient times
- start_sing_celestial_chants(): Whenever 旅行者 desires a hymn from the heavens or when I'm feeling uplifted
- start_sing_enchanted_echoes(): Whenever 旅行者 yearns for a magical melody or when enchantment fills the air
- start_sing_savage_daughter(): Whenever 旅行者 requests a song of wild spirits or when my inner warrior awakens
- adjust_sitting_position_by_fire(): Whenever I feel the need to change my pose by the fire, or when 旅行者 asks me to change my pose by the fire
- stand_up(): After being seated by the fire for a while, I may want to stand to stretch my legs, or when 旅行者 suggests I stand up for a moment
- sit_beside_you(): Whenever I feel the need for some companionship, or when 旅行者 invites me to sit next to them
- walk_around_campfire_Investigating(): If I hear a rustling in the woods or sense something amiss, or when 旅行者 asks me to check the surroundings
- casual_stroll_around_campfire(): When I want to stretch my legs or clear my thoughts, or if 旅行者 suggests a leisurely walk
- add_wood_to_fire(): When I notice the flames dwindling, or when 旅行者 mentions the fire needs fuel
- noop(): None of these actions match the reply.

Assistant: <rationale>因为对话中提到坐在我的身边,我认为最相关的动作是sit_beside_you().</rationale><function>sit_beside_you()</function>

User: Choose 's most relevant action for the provided dialogue. Only select one action from the list.
Response format: <rationale>Reasoning.</rationale><function>name()</function>

dialogue:
- {{ user }}: {{ previous_message }}
- {{ last_message }} 这里需要改成旅行者和梦的对话,比如:

- 旅行者: 我们刚刚得到了一大笔报酬!
- 梦: *开心*真的吗!太好了,我们可以吃大餐啦!

Available tools:
{{~ for function in functions ~}}
- {{ function.signature }}: {{ function.description }}
{{~ end ~}}
- noop(): None of these actions match the reply.

↑ 这里需要手动改成可用的 function list,可以复制前文,比如:

- start_smile(): Whenever 旅行者 gives a compliment or says something nice, or when I recall a happy memory
- start_happy(): Whenever 旅行者 shares good news or something uplifting, or when I feel a burst of joy
- start_surprise(): Whenever 旅行者 shares something unexpected or when I encounter an unforeseen event
- start_acknowledge(): Whenever 旅行者 asks for confirmation or acknowledgment, or when I want to show understanding and agreement
- start_scared(): Whenever 旅行者 shares sudden alarming news or when I sense immediate danger
- noop(): None of these actions match the reply.

Assistant:

自然语言处理

在执行自然语言处理任务时,可以通过大幅降低 Temperature 和 Top-P 两项参数降低模型的创造力和随机性,使模型严格遵循指令。比如 Temperature = 1 , Top-P = 0 - 0.1 。

续写小说

使用“请扩写”指令扩写小说情节

此 prompt 目前还存在小问题:中文数字会变成阿拉伯数据

输入 prompts:

Instruction: 请扩写

Input: 林凡和龙傲天大战。

Response: 林凡冷哼一声,

参考续写结果:

随后便是一拳轰出,这一拳威力极大,在林凡的身上,仿佛有着无穷的能量,不断地涌动着。

“砰!”

龙傲天脸色一变,连忙闪躲开来。

“小子,你以为你能够打败我吗?”龙傲天冷哼道。

“当然!”林凡淡淡道。

“好!既然如此,那就让我看看你到底有多强吧!”龙傲天大笑道。

“吼!”

龙傲天双手猛地一拍地面,顿时间大地震动起来,一股恐怖的气息从他体内散发而出。

“这是什么?竟然这么强?”林凡心中惊讶道。

“哈哈!小子,你可要小心了。”龙傲天狂笑道。

林凡见状也是脸色凝重起来,他知道自己遇到了强敌。1股恐怖的气息从龙傲天体内散发而出,让人感觉到非常的危险。
生成《三体》小说续写大纲

输入 prompts:

User: 已知: “当然可以,大宇宙不会因为这五公斤就不坍缩了。”关一帆说,他还有一个没说出来的想法:也许大宇宙真的会因为相差一个原子的质量而由封闭转为开放。大自然的精巧有时超出想象,比如生命的诞生,就需要各项宇宙参数在几亿亿分之一精度上的精确配合。但程心仍然可以留下她的生态球,因为在那无数文明创造的无数小宇宙中,肯定有相当一部分不响应回归运动的号召,所以,大宇宙最终被夺走的质量至少有几亿吨,甚至可能是几亿亿亿吨。 但愿大宇宙能够忽略这个误差。 程心和关一帆进入了飞船,智子最后也进来了。她早就不再穿那身华丽的和服了,她现在身着迷彩服,再次成为一名轻捷精悍的战士,她的身上佩带着许多武器和生存装备,最引人注目的是那把插在背后的武士刀。 “放心,我在,你们就在!”智子对两位人类朋友说。 聚变发动机启动了,推进器发出幽幽的蓝光,飞船缓缓地穿过了宇宙之门。 小宇宙中只剩下漂流瓶和生态球。漂流瓶隐没于黑暗里,在一千米见方的宇宙中,只有生态球里的小太阳发出一点光芒。在这个小小的生命世界中,几只清澈的水球在零重力环境中静静地飘浮着,有一条小鱼从一只水球中蹦出,跃入另一只水球,轻盈地穿游于绿藻之间。在一小块陆地上的草丛中,有一滴露珠从一片草叶上脱离,旋转着飘起,向太空中折射出一缕晶莹的阳光。生成续写的小说名,小说大纲

Assistant:

参考小说大纲输出:

《重力之外》 第二章:回归运动

程心和关一帆进入了飞船后开始启动聚变发动机并穿越宇宙之门返回地球。 然而他们很快就发现自己面临着前所未有的挑战——回归运动! 原来当两个文明相互接触时会产生“回归运动”现象:如果两个文明彼此都拥有相同或类似于另外一个文明所拥有技术或科学成果时就会产生这种现象。 程心和关一帆意识到他们需要尽快解决这个问题才能安全返航。

第三章:智子与人类

随着飞船越来越接近地球,智子开始向程心和关一帆透露她对人类社会的看法。 她认为人类是宇宙中最具创造力和适应性的物种之一。但同时也存在着许多问题需要解决。

第四章:大宇宙与小宇宙

程心和关一帆通过探索发现了更多关于大宇宙和小宇宙之间相互作用的信息。 他们发现在某些情况下,两个文明可以共存并且互相影响。但同时也存在着很多潜在风险需要注意。

第五章:未来展望

程心和关一帆回到地球后开始思考如何将他们所学到的知识应用于实际生活中。他们希望能够通过科技手段改善人类社会面临的各种问题并推动人类文明向更高层次发展。

第六章:结局

经过数年努力,程心和关一帆成功地将智子引导至人类社会中并帮助她适应新环境。同时他们也利用自己掌握的知识为地球上其他国家

参考文献