[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-BlinkDL--RWKV-LM":3,"tool-BlinkDL--RWKV-LM":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",150037,2,"2026-04-10T23:33:47",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",108322,"2026-04-10T11:39:34",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},6121,"gemini-cli","google-gemini\u002Fgemini-cli","gemini-cli 是一款由谷歌推出的开源 AI 命令行工具，它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言，它提供了一条从输入提示词到获取模型响应的最短路径，无需切换窗口即可享受智能辅助。\n\n这款工具主要解决了开发过程中频繁上下文切换的痛点，让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用，还是执行复杂的 Git 操作，gemini-cli 都能通过自然语言指令高效处理。\n\n它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口，具备出色的逻辑推理能力；内置 Google 搜索、文件操作及 Shell 命令执行等实用工具；更独特的是，它支持 MCP（模型上下文协议），允许用户灵活扩展自定义集成，连接如图像生成等外部能力。此外，个人谷歌账号即可享受免费的额度支持，且项目基于 Apache 2.0 协议完全开源，是提升终端工作效率的理想助手。",100752,"2026-04-10T01:20:03",[52,13,15,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":32,"last_commit_at":59,"category_tags":60,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":76,"owner_email":76,"owner_twitter":77,"owner_website":78,"owner_url":79,"languages":80,"stars":97,"forks":98,"last_commit_at":99,"license":100,"difficulty_score":10,"env_os":101,"env_gpu":102,"env_ram":103,"env_deps":104,"category_tags":113,"github_topics":114,"view_count":10,"oss_zip_url":76,"oss_zip_packed_at":76,"status":17,"created_at":129,"updated_at":130,"faqs":131,"releases":157},3268,"BlinkDL\u002FRWKV-LM","RWKV-LM","RWKV (pronounced RwaKuv) is an RNN with great LLM performance, which can also be directly trained like a GPT transformer (parallelizable). We are at RWKV-7 \"Goose\". So it's combining the best of RNN and transformer - great performance, linear time, constant space (no kv-cache), fast training, infinite ctx_len, and free sentence embedding.","RWKV-LM 是一款突破性的开源人工智能架构，旨在融合循环神经网络（RNN）的高效性与 Transformer 模型的强大性能。它成功解决了传统大语言模型在处理长文本时显存占用随长度线性增长、推理速度受限以及需要复杂键值缓存（KV-cache）的痛点。\n\n作为 Linux 基金会 AI 项目，RWKV 目前最新迭代至 RWKV-7\"Goose\"版本。其核心亮点在于实现了“线性时间复杂度”与“常数空间复杂度”，这意味着无论输入上下文多长，其运行速度和显存占用始终保持恒定，无需注意力机制即可支持无限长度的上下文窗口。此外，RWKV 支持像 GPT 一样进行并行化训练，大幅提升了训练效率，并天然具备免费的句子嵌入能力。\n\n这款工具非常适合追求高效部署的开发者、需要处理超长文档的研究人员，以及希望在移动端或低显存设备上运行大模型的技术爱好者。凭借其在 RTX 5090 等硬件上展现出的极高吞吐量，RWKV-LM 为构建下一代低成本、高性能的多模态应用提供了坚实的技术基础，让无限上下文的智能体验变得触手可及。","# RWKV: Parallelizable RNN with Transformer-level LLM Performance (pronounced as \"RwaKuv\" (rʌkuv in IPA), from 4 major params: R W K V)\n\nRWKV website: https:\u002F\u002Frwkv.com (with 150+ papers training various RWKV models)\n\nRWKV twitter: https:\u002F\u002Ftwitter.com\u002FBlinkDL_AI (lastest news)\n\nRWKV discord: https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc\n\nRWKV-7 \"Goose\" is the strongest **linear-time** & **constant-space** (no kv-cache) & **attention-free** & 100% RNN architecture on this planet at this moment, suitable for LLM and multimodal applications and more (see [rwkv.com](https:\u002F\u002Frwkv.com)).\n\nRWKV-7 is a [meta-in-context learner](https:\u002F\u002Fraw.githubusercontent.com\u002FBlinkDL\u002FRWKV-LM\u002Fmain\u002Fhttps:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_2d63b5cf5e4f.png), test-time-training its state on the context via in-context gradient descent at every token.\n\nRWKV is a [Linux Foundation AI project](https:\u002F\u002Flfaidata.foundation\u002Fprojects\u002Frwkv\u002F), so totally free. RWKV runtime is [already in Windows & Office](https:\u002F\u002Fx.com\u002FBlinkDL_AI\u002Fstatus\u002F1831012419508019550).\n\nYou are welcome to ask the RWKV community (such as [RWKV discord](https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc)) for advice on upgrading your attention\u002Fssm models to rwkv7 models :)\n\n---\n\nRWKV Chat: https:\u002F\u002Frwkv.halowang.cloud\u002F (local inference for mobile\u002Fdesktop) and https:\u002F\u002Fgithub.com\u002FRWKV-APP\u002FRWKV_APP\n\nLatest RWKV weights: https:\u002F\u002Fhuggingface.co\u002FBlinkDL\n\nGGUF: https:\u002F\u002Fhuggingface.co\u002Fcollections\u002Fshoumenchougou\u002Frwkv7-gxx-gguf\n\nEfficient inference: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FAlbatross\n* 145+ token\u002Fs RWKV-7 7.2B fp16 bsz1 decoding @ RTX5090 (always const speed & vram)\n* 10250+ token\u002Fs RWKV-7 7.2B fp16 bsz960 decoding @ RTX5090 (always const speed & vram)\n* 9650+ token\u002Fs RWKV-7 7.2B fp16 bsz320 decoding @ RTX5090 (always const speed & vram)\n* 11289 token\u002Fs RWKV-7 7.2B fp16 bsz1 prefill @ RTX5090 (always const speed & vram)\n\nMobile inference library: https:\u002F\u002Fgithub.com\u002FMollySophia\u002Frwkv-mobile\n\n---\n\nFast RWKV-7 CUDA kernels (vanilla, state-tuning, state-passing infctx): https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-CUDA\u002Ftree\u002Fmain\u002Frwkv7_fast_fused\n\nMy current RWKV7 kernel is 2x slower for 0.1\u002F0.4B vs optimized transformer, but you can reach good speed with 7B+. RWKV7 7.2B training on 4x8xH100 ctx8192 zero2+cp = 206k tokens\u002Fs.\n\n**Please use https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v7\u002Ftrain_temp as RWKV-7 reference implementation**. The default config only requires 1 GPU with 10G VRAM (you can reduce bsz if you have less VRAM), so it's easy to test.\n\nSimplified RWKV-7 training demo: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Ftrain_temp\u002Frwkv7_train_simplified.py\n\n**Important** (all shown in rwkv7_train_simplified.py):\n* Use PreLN LayerNorm (instead of RMSNorm) for RWKV. I think it's related to better initial state, because I am not using trainable initial state (found it useless when using LayerNorm).\n* Only apply weight decay to large matrix parameters (basically projections) in your model instead of all parameters. THIS IS VERY IMPORTANT.\n* Use correct initialization.\n\nNote FLA RWKV-7 is NOT aligned with reference implementation yet, and you will get less performance.\n\nThis is because RWKV-7 is the whole model with carefully set stuffs, including different init \u002F wd \u002F lr for each parameter, so it's readily scalable and very stable (spike-free).\n\nBut the price to pay is there is no good simple \"RWKV-7 layer\" because a pytorch layer can't make sure itself is using correct init and hyperparameters.\n\nSo if you need to use RWKV-7 for another task, please study train_temp code (only several hundred lines) and change it to suit you.\n\nSee: https:\u002F\u002Fgithub.com\u002FYS-Tang\u002FRWKV-FLA-comparison\n\n\u003Cimg width=\"3318\" height=\"2475\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_9f213610230e.png\" \u002F>\n\n\u003Cimg width=\"2656\" height=\"1956\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_61ff79c925f0.png\" \u002F>\n\n===\n\nRWKV-8:\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_93d323fcd470.png\">\n\nImproving RNNs: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-8.md\n\n===\n\nHistory of RWKV (from v1 to v7): [https:\u002F\u002Fwiki.rwkv.com](https:\u002F\u002Fwiki.rwkv.com\u002F) (note: AI-written. might contain errors)\n\nGradio Demo 1: https:\u002F\u002Fhuggingface.co\u002Fspaces\u002FBlinkDL\u002FRWKV-Gradio-1\n\nGradio Demo 2: https:\u002F\u002Fhuggingface.co\u002Fspaces\u002FBlinkDL\u002FRWKV-Gradio-2\n\nWebGPU Demo: https:\u002F\u002Fcryscan.github.io\u002Fweb-rwkv-puzzles\u002F#\u002Fchat\n\n===\n\nRWKV-Runner GUI: https:\u002F\u002Fgithub.com\u002FjosStorer\u002FRWKV-Runner\u002Freleases\n\nAi00 Server: https:\u002F\u002Fgithub.com\u002FAi00-X\u002Fai00_server\n\nRWKV pip pkg: https:\u002F\u002Fpypi.org\u002Fproject\u002Frwkv\u002F\n\nPEFT (Lora etc.): https:\u002F\u002Fgithub.com\u002FJL-er\u002FRWKV-PEFT\n\nRLHF: https:\u002F\u002Fgithub.com\u002FOpenMOSE\u002FRWKV-LM-RLHF\n\n400+ RWKV projects: https:\u002F\u002Fgithub.com\u002Fsearch?o=desc&q=rwkv&s=updated&type=Repositories\n\n**Faster RWKV-7 kernels**: https:\u002F\u002Fgithub.com\u002Fjohanwind\u002Fwind_rwkv\n\n===\n\nRWKV-5\u002F6 Eagle\u002FFinch paper: https:\u002F\u002Farxiv.org\u002Fabs\u002F2404.05892\n\nChat demo code: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FAPI_DEMO_CHAT.py\n\n**RWKV-7 demo code**: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v7\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo.py (GPT-like mode)\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo_rnn.py (RNN mode)\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo_fast.py (Both mode, fastest)\n\nRWKV-6 demo code: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Frwkv_v6_demo.py\n\nRWKV-6 demo code: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n## HOW TO TRAIN RWKV-7\u002F6\u002F5 on MiniPile (1.5G tokens) ##\n\nFor reference, use python 3.10+, torch 2.5+, cuda 12.4+, latest deepspeed, but **keep pytorch-lightning==1.9.5**\n\n**Train RWKV-7:**\n```\n# you can use latest torch + latest cuda (not limited to cu121)\npip install torch --upgrade --extra-index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu121\npip install pytorch-lightning==1.9.5 deepspeed wandb ninja --upgrade\n\n# train RWKV-7\ncd RWKV-v7\u002Ftrain_temp\u002F \n\n# download minipile .bin .idx to train_temp\u002Fdata first (check demo-training-prepare.sh)\n# this will generate the initial weight rwkv-init.pth in out\u002F......\u002F\nsh .\u002Fdemo-training-prepare.sh\n\n# this will load rwkv-init.pth and train the model. you may want to log in to wandb first\nsh .\u002Fdemo-training-run.sh\n\nyour out\u002F......\u002Ftrain_log.txt should have losses similar to:\n0 4.875856 131.0863 0.00059975 2025-04-24 02:23:42.481256 0\n1 4.028621 56.1834 0.00059899 2025-04-24 02:28:16.674463 1\n2 3.801625 44.7739 0.00059773 2025-04-24 02:32:51.059568 2\n3 3.663070 38.9808 0.00059597 2025-04-24 02:37:25.409892 3\n4 3.578974 35.8368 0.00059371 2025-04-24 02:41:59.711315 4\n5 3.510906 33.4786 0.00059096 2025-04-24 02:46:33.990839 5\n6 3.462345 31.8917 0.00058771 2025-04-24 02:51:08.378331 6\n7 3.412196 30.3318 0.00058399 2025-04-24 02:55:42.927474 7\n8 3.376724 29.2747 0.00057978 2025-04-24 03:00:17.504665 8\n9 3.336911 28.1321 0.00057511 2025-04-24 03:04:52.006063 9\n10 3.313411 27.4787 0.00056999 2025-04-24 03:09:27.563336 10\n11 3.295895 27.0016 0.00056441 2025-04-24 03:14:01.786079 11\n```\n\nRWKV-7 weight example for 1.5B (L24-D2048, vocab 65536):\n\n**Make sure you only apply wd to large tensors (with \"wdecay\" in comment) here**, or the performance will be much worse.\n\n| name                | shape         | comment      | initialization  |\n|---------------------|---------------|--------------|-----------------|\n| emb.weight          | [65536, 2048] | wdecay       | see code        |\n| blocks.0.ln0.weight | [2048]        | for layer 0  | 1               |\n| blocks.0.ln0.bias   | [2048]        | for layer 0  | 0               |\n|                     |               |              |                 |\n| blocks.*.ln1.weight | [2048]        |              | 1               |\n| blocks.*.ln1.bias   | [2048]        |              | 0               |\n| blocks.*.att.x_r    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.x_w    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.x_k    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.x_v    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.x_a    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.x_g    | [1, 1, 2048]  |              | see code        |\n| blocks.*.att.w0     | [1, 1, 2048]  | lr 2x        | see code        |\n| blocks.*.att.w1     | [2048, 96]    |              | 0               |\n| blocks.*.att.w2     | [96, 2048]    |              | see code        |\n| blocks.*.att.a0     | [1, 1, 2048]  |              | 0               |\n| blocks.*.att.a1     | [2048, 96]    |              | 0               |\n| blocks.*.att.a2     | [96, 2048]    |              | see code        |\n| blocks.*.att.v0     | [1, 1, 2048]  | for layer 1+ | 1               |\n| blocks.*.att.v1                | [2048, 64]   | for layer 1+ | 0         |\n| blocks.*.att.v2                | [64, 2048]   | for layer 1+ | see code  |\n| blocks.*.att.g1                | [2048, 256]  |              | 0         |\n| blocks.*.att.g2                | [256, 2048]  |              | see code  |\n| blocks.*.att.k_k               | [1, 1, 2048] |              | 1         |\n| blocks.*.att.k_a               | [1, 1, 2048] |              | 1         |\n| blocks.*.att.r_k               | [32, 64]     |              | 0         |\n| blocks.*.att.receptance.weight | [2048, 2048] | wdecay       | see code  |\n| blocks.*.att.key.weight        | [2048, 2048] | wdecay       | see code  |\n| blocks.*.att.value.weight      | [2048, 2048] | wdecay       | see code  |\n| blocks.*.att.output.weight     | [2048, 2048] | wdecay       | 0         |\n| blocks.*.att.ln_x.weight       | [2048]       |              | see code  |\n| blocks.*.att.ln_x.bias         | [2048]       |              | 0         |\n|                                |              |              |           |\n| blocks.*.ln2.weight            | [2048]       |              | 1         |\n| blocks.*.ln2.bias              | [2048]       |              | 0         |\n| blocks.*.ffn.x_k               | [1, 1, 2048] |              | see code  |\n| blocks.*.ffn.key.weight        | [8192, 2048] | wdecay       | see code  |\n| blocks.*.ffn.value.weight      | [2048, 8192] | wdecay       | 0         |\n|                                |              |              |           |\n| ln_out.weight | [2048]        |        | 1         |\n| ln_out.bias   | [2048]        |        | 0         |\n| head.weight   | [65536, 2048] | wdecay | see code  |\n\nTrain RWKV-6: use \u002FRWKV-v5\u002F and use --my_testing \"x060\" in demo-training-prepare.sh and demo-training-run.sh\n\nYour loss curve should look almost exactly the same as this, with the same ups and downs (if you use the same bsz & config):\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_f75767ee133e.png\" width=\"500\">\n\nYou can run your model using https:\u002F\u002Fpypi.org\u002Fproject\u002Frwkv\u002F (use \"rwkv_vocab_v20230424\" instead of \"20B_tokenizer.json\")\n\nUse https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fmake_data.py to prepare binidx data from jsonl, and compute \"--my_exit_tokens\" and \"--magic_prime\".\n\nUse https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fcompute_magic_prime.py to compute \"--my_exit_tokens\" and \"--magic_prime\" for existing binidx.\n\nMuch faster tokenizer of large data: https:\u002F\u002Fgithub.com\u002Fcahya-wirawan\u002Fjson2bin https:\u002F\u002Fgithub.com\u002Fcahya-wirawan\u002Frwkv-tokenizer https:\u002F\u002Fgithub.com\u002Fm8than\u002FRWKV-World-Tokenizer-CPP\n\nThe \"epoch\" in train.py is \"mini-epoch\" (not real epoch. only for convenience), and 1 mini-epoch = 40320 * ctx_len tokens.\n\nFor example, if your binidx has 1498226207 tokens and ctxlen=4096, set \"--my_exit_tokens 1498226207\" (this will override epoch_count), and it will be 1498226207\u002F(40320 * 4096) = 9.07 miniepochs. The trainer will auto-exit after \"--my_exit_tokens\" tokens. Set \"--magic_prime\" to the largest 3n+2 prime smaller than datalen\u002Fctxlen-1 (= 1498226207\u002F4096-1 = 365776), which is \"--magic_prime 365759\" in this case.\n\nsimple: prepare SFT jsonl => repeat your SFT data 3 or 4 times in make_data.py. more repetition leads to overfitting.\n\nadvanced: repeat your SFT data 3 or 4 times in your jsonl (note make_data.py will shuffle all jsonl items) => add some base data (such as slimpajama) to your jsonl => and only repeat 1 times in make_data.py.\n\n**Fix training spikes**: see the \"Fixing RWKV-6 Spikes\" part on this page. \n\nOr use RWKV-7 (much better). RWKV-7 is very stable and spike-free (verified for 0.1\u002F0.4\u002F1.5\u002F2.9b):\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_e49feae0927a.png\" width=\"500\">\n\n**Simple inference for RWKV-6**: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n**Simple inference for RWKV-5**: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v5_demo.py\n\n**Note: In [state = kv + w * state] everything must be in fp32 because w can be very close to 1. So we can keep state and w in fp32, and convert kv to fp32.**\n\nlm_eval: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002Frun_lm_eval.py\n\n**Tips for small model \u002F small data**: When I train RWKV music models, I use deep & narrow (such as L29-D512) dimensions, and apply wd and dropout (such as wd=2 dropout=0.02). Note RWKV-LM dropout is very effective - use 1\u002F4 of your usual value.\n\n## HOW TO TRAIN RWKV-7 on Pile (332G tokens) ##\n\nSee https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fdemo-training-prepare-v7-pile.sh and https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fdemo-training-run-v7-pile.sh\n\nGet these files first:\n\npile_20B_tokenizer_text_document.bin (664230651068 bytes)\n\npile_20B_tokenizer_text_document.idx (4212099722 bytes)\n\n### HOW TO FINETUNE RWKV-5 MODELS ###\n\nUse .jsonl format for your data (see https:\u002F\u002Fhuggingface.co\u002FBlinkDL\u002Frwkv-5-world for formats).\n\nUse https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fmake_data.py to tokenizer it using World tokenizer into binidx, suitable for finetuning World models.\n\nRename the base checkpoint in your model folder to rwkv-init.pth, and change the training commands to use --n_layer 32 --n_embd 4096 --vocab_size 65536 --lr_init 1e-5 --lr_final 1e-5 for 7B.\n\n0.1B = --n_layer 12 --n_embd 768 \u002F\u002F 0.4B = --n_layer 24 --n_embd 1024 \u002F\u002F 1.5B = --n_layer 24 --n_embd 2048 \u002F\u002F 3B = --n_layer 32 --n_embd 2560 \u002F\u002F 7B = --n_layer 32 --n_embd 4096\n\n### State-tuning (tuning the initial state. zero inference overhead)\n\nCurrently unoptimized implementation, takes same vram as full SFT\n\n```--train_type \"states\" --load_partial 1 --lr_init 1 --lr_final 0.01 --warmup_steps 10 (yes, use very high LR)```\n\nuse rwkv 0.8.26+ to auto-load the trained \"time_state\" \n\n### Initializing RWKV 5\u002F6 Models ###\n\nWhen you train RWKV from scratch, try my initialization for best performance. Check generate_init_weight() of src\u002Fmodel.py:\n```\nemb.weight => nn.init.uniform_(a=-1e-4, b=1e-4)\n(Note ln0 of block0 is the layernorm for emb.weight)\nhead.weight => nn.init.orthogonal_(gain=0.5*sqrt(n_vocab \u002F n_embd))\n\natt.receptance.weight => nn.init.orthogonal_(gain=1)\natt.key.weight => nn.init.orthogonal_(gain=0.1)\natt.value.weight => nn.init.orthogonal_(gain=1)\natt.gate.weight => nn.init.orthogonal_(gain=0.1)\natt.output.weight => zero\n\natt.ln_x.weight (groupnorm) => ((1 + layer_id) \u002F total_layers) ** 0.7\n\nffn.key.weight => nn.init.orthogonal_(gain=1)\nffn.value.weight => zero\nffn.receptance.weight => zero\n```\n!!! If you are using positional embedding, maybe it's better to remove block.0.ln0 and use default initialization for emb.weight instead of my uniform_(a=-1e-4, b=1e-4) !!!\n\n### Fixing RWKV-6 Spikes ###\n\n0. upgrade to RWKV-7. It's very stable.\n\n1. when training from scratch, add \"k = k * torch.clamp(w, max=0).exp()\" before \"RUN_CUDA_RWKV6(r, k, v, w, u)\", and remember to change your inference code too. you will see faster convergence.\n\n2. use \"--adam_eps 1e-18\"\n\n3. \"--beta2 0.95\" if you see spikes\n\n4. in trainer.py do \"lr = lr * (0.01 + 0.99 * trainer.global_step \u002F w_step)\" (originally 0.2 + 0.8), and \"--warmup_steps 20\"\n\n5. \"--weight_decay 0.1\" leads to better final loss if you are training lots of data. set lr_final to 1\u002F100 of lr_init when doing this.\n\n### Misc\n\nRWKV-7 can do math. See https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FResearch\u002Frwkv7-g0-7.2b.md for details.\n\n\u003Cimg width=\"555\" height=\"784\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_154cc66384ef.png\" \u002F>\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_83e9bdbfc056.png\">\n\n## Introducing RWKV\n\nRWKV is an RNN with Transformer-level LLM performance, which can also be directly trained like a GPT transformer (parallelizable). And it's 100% attention-free. You only need the hidden state at position t to compute the state at position t+1. You can use the \"GPT\" mode to quickly compute the hidden state for the \"RNN\" mode.\n\nSo it's combining the best of RNN and transformer - **great performance, fast inference, saves VRAM, fast training, \"infinite\" ctx_len, and free sentence embedding** (using the final hidden state).\n\n**All latest RWKV weights:** https:\u002F\u002Fhuggingface.co\u002FBlinkDL\n\n**HF-compatible RWKV weights:** https:\u002F\u002Fhuggingface.co\u002FRWKV\n\n```python\nos.environ[\"RWKV_JIT_ON\"] = '1'\nos.environ[\"RWKV_CUDA_ON\"] = '0' # if '1' then use CUDA kernel for seq mode (much faster)\nfrom rwkv.model import RWKV                         # pip install rwkv\nmodel = RWKV(model='\u002Ffsx\u002FBlinkDL\u002FHF-MODEL\u002Frwkv-4-pile-1b5\u002FRWKV-4-Pile-1B5-20220903-8040', strategy='cuda fp16')\n\nout, state = model.forward([187, 510, 1563, 310, 247], None)   # use 20B_tokenizer.json\nprint(out.detach().cpu().numpy())                   # get logits\nout, state = model.forward([187, 510], None)\nout, state = model.forward([1563], state)           # RNN has state (use deepcopy if you want to clone it)\nout, state = model.forward([310, 247], state)\nprint(out.detach().cpu().numpy())                   # same result as above\n```\n\nnanoRWKV: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FnanoRWKV (does not require custom CUDA kernel to train, works for any GPU\u002FCPU)\n\n**Cool Community RWKV Projects**:\n\nAll (400+) RWKV projects: https:\u002F\u002Fgithub.com\u002Fsearch?o=desc&q=rwkv&s=updated&type=Repositories\n\nhttps:\u002F\u002Fgithub.com\u002FOpenGVLab\u002FVision-RWKV Vision RWKV\n\nhttps:\u002F\u002Fgithub.com\u002Ffeizc\u002FDiffusion-RWKV Diffusion RWKV\n\nhttps:\u002F\u002Fgithub.com\u002Fcgisky1980\u002Fai00_rwkv_server Fastest WebGPU inference (nVidia\u002FAMD\u002FIntel)\n\nhttps:\u002F\u002Fgithub.com\u002Fcryscan\u002Fweb-rwkv backend for ai00_rwkv_server\n\nhttps:\u002F\u002Fgithub.com\u002FsaharNooby\u002Frwkv.cpp Fast CPU\u002FcuBLAS\u002FCLBlast inference: int4\u002Fint8\u002Ffp16\u002Ffp32\n\nhttps:\u002F\u002Fgithub.com\u002FJL-er\u002FRWKV-PEFT lora\u002Fpissa\u002FQlora\u002FQpissa\u002Fstate tuning\n\nhttps:\u002F\u002Fgithub.com\u002FRWKV\u002FRWKV-infctx-trainer Infctx trainer\n\nhttps:\u002F\u002Fgithub.com\u002Fdaquexian\u002Ffaster-rwkv\n\nhttps:\u002F\u002Fgithub.com\u002Fmlc-ai\u002Fmlc-llm\u002Fpull\u002F1275\n\nhttps:\u002F\u002Fgithub.com\u002FTheRamU\u002FFay\u002Fblob\u002Fmain\u002FREADME_EN.md Digital Assistant with RWKV\n\nhttps:\u002F\u002Fgithub.com\u002Fharrisonvanderbyl\u002Frwkv-cpp-cuda Fast GPU inference with cuda\u002Famd\u002Fvulkan\n\n**RWKV v6 in 250 lines** (with tokenizer too): https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n**RWKV v5 in 250 lines** (with tokenizer too): https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v5_demo.py\n\n**RWKV v4 in 150 lines** (model, inference, text generation): https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_in_150_lines.py\n\n**RWKV v4 preprint** https:\u002F\u002Farxiv.org\u002Fabs\u002F2305.13048\n\n**RWKV v4 introduction, and in 100 lines of numpy**: https:\u002F\u002Fjohanwind.github.io\u002F2023\u002F03\u002F23\u002Frwkv_overview.html https:\u002F\u002Fjohanwind.github.io\u002F2023\u002F03\u002F23\u002Frwkv_details.html\n\n![RWKV-7](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_2d63b5cf5e4f.png)\n\n![MQAR](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_aa475cbdaa87.png)\n\n![RWKV-paper](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_023bf1f94811.png)\n\nRWKV v6 illustrated:\n\n![RWKV-v6](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_05ed34639d18.png)\n\n![RWKV-v5-benchmark-1](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_77fd3e0ec9fb.png)\n\nA cool paper (Spiking Neural Network) using RWKV: https:\u002F\u002Fgithub.com\u002Fridgerchu\u002FSpikeGPT\n\nYou are welcome to join the RWKV discord https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc to build upon it. We have plenty of potential compute (A100 40Gs) now (thanks to Stability and EleutherAI), so if you have interesting ideas I can run them.\n\n![RWKV-eval2](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_aed14114120c.png)\n\nRWKV [loss vs token position] for 10000 ctx4k+ documents in Pile. RWKV 1B5-4k is mostly flat after ctx1500, but 3B-4k and 7B-4k and 14B-4k have some slopes, and they are getting better. This debunks the old view that RNNs cannot model long ctxlens. We can predict that RWKV 100B will be great, and RWKV 1T is probably all you need :)\n\n![RWKV-ctxlen](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_7efa80a9456d.png)\n\nChatRWKV with RWKV 14B ctx8192:\n\n![RWKV-chat](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_31d8cb55f4f5.png)\n\nI believe RNN is a better candidate for fundamental models, because: (1) It's more friendly for ASICs (no kv cache). (2) It's more friendly for RL. (3) When we write, our brain is more similar to RNN. (4) The universe is like an RNN too (because of locality). Transformers are non-local models.\n\nRWKV-3 1.5B on A40 (tf32) = always 0.015 sec\u002Ftoken, tested using simple pytorch code (no CUDA), GPU utilization 45%, VRAM 7823M\n\nGPT2-XL 1.3B on A40 (tf32) = 0.032 sec\u002Ftoken (for ctxlen 1000), tested using HF, GPU utilization 45% too (interesting), VRAM 9655M\n\nTraining speed: (new training code) RWKV-4 14B BF16 ctxlen4096 = 114K tokens\u002Fs on 8x8 A100 80G (ZERO2+CP). (old training code) RWKV-4 1.5B BF16 ctxlen1024 = 106K tokens\u002Fs on 8xA100 40G.\n\nI am doing image experiments too (For example: https:\u002F\u002Fhuggingface.co\u002FBlinkDL\u002Fclip-guided-binary-autoencoder) and RWKV will be able to do txt2img diffusion :) My idea: 256x256 rgb image -> 32x32x13bit latents -> apply RWKV to compute transition probability for each of the 32x32 grid -> pretend the grids are independent and \"diffuse\" using these probabilities.\n\nSmooth training - no loss spikes! (lr & bsz change around 15G tokens)\n![RWKV-loss](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_ef419aff7eb2.png)\n\n![RWKV-eval](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_66fbbf6b4556.png)\n\nAll of the trained models will be open-source. Inference is very fast (only matrix-vector multiplications, no matrix-matrix multiplications) even on CPUs, so you can even run a LLM on your phone.\n\nHow it works: RWKV gathers information to a number of channels, which are also decaying with different speeds as you move to the next token. It's very simple once you understand it.\n\n**RWKV is parallelizable because the time-decay of each channel is data-independent (and trainable)**. For example, in usual RNN you can adjust the time-decay of a channel from say 0.8 to 0.5 (these are called \"gates\"), while in RWKV you simply move the information from a W-0.8-channel to a W-0.5-channel to achieve the same effect. Moreover, you can fine-tune RWKV into a non-parallelizable RNN (then you can use outputs of later layers of the previous token) if you want extra performance.\n\n![RWKV-formula](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_a80f544a3ba4.png)\n\nHere are some of my TODOs. Let's work together :)\n\n* HuggingFace integration (check https:\u002F\u002Fgithub.com\u002Fhuggingface\u002Ftransformers\u002Fissues\u002F17230\n), and optimized CPU & iOS & Android & WASM & WebGL inference. RWKV is a RNN and very friendly for edge devices. Let's make it possible to run a LLM on your phone. \n\n* Test it on bidirectional & MLM tasks, and image & audio & video tokens. I think RWKV can support Encoder-Decoder via this: for each decoder token, use a learned mixture of [decoder previous hidden state] & [encoder final hidden state]. Hence all decoder tokens will have access to the encoder output.\n\n* Now training RWKV-4a with one single tiny extra attention (just a few extra lines comparing with RWKV-4) to further improve some difficult zeroshot tasks (such as LAMBADA) for smaller models. See https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fcommit\u002Fa268cd2e40351ee31c30c5f8a5d1266d35b41829\n\nUser feedback:\n> *I've so far toyed around the character-based model on our relatively small pre-training dataset (around 10GB of text), and the results are extremely good - similar ppl to models taking much, much longer to train.*\n\n> *dear god rwkv is fast. i switched to another tab after starting training it from scratch & when i returned it was emitting plausible english & maori words, i left to go microwave some coffee & when i came back it was producing fully grammatically correct sentences.*\n\nTweet from Sepp Hochreiter (thank you!): https:\u002F\u002Ftwitter.com\u002FHochreiterSepp\u002Fstatus\u002F1524270961314484227\n\nYou can find me (BlinkDL) in the EleutherAI Discord too: https:\u002F\u002Fwww.eleuther.ai\u002Fget-involved\u002F\n\n![RWKV-demo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_eda3c01b6f82.png)\n\n## Quick start\n\n**IMPORTANT: Use deepspeed==0.7.0 pytorch-lightning==1.9.5 torch==1.13.1+cu117 and cuda 11.7.1 or 11.7 (note torch2 + deepspeed has weird bugs and hurts model performance)**\n\nUse https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v4neo (latest code, compatible with v4).\n\nHere is a great prompt for testing Q&A of LLMs. Works for any model: (found by minimizing ChatGPT ppls for RWKV 1.5B)\n```python\nprompt = f'\\nQ & A\\n\\nQuestion:\\n{qq}\\n\\nDetailed Expert Answer:\\n' # let the model generate after this\n```\n\n### Inference\n\n**Run RWKV-4 Pile models:** Download models from https:\u002F\u002Fhuggingface.co\u002FBlinkDL. Set TOKEN_MODE = 'pile' in run.py and run it. It's fast even on CPU (the default mode).\n\n**Colab for RWKV-4 Pile 1.5B**: https:\u002F\u002Fcolab.research.google.com\u002Fdrive\u002F1F7tZoPZaWJf1fsCmZ5tjw6sYHiFOYVWM\n\nRun RWKV-4 Pile models in your browser (and onnx version): see this issue https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F7\n\nRWKV-4 Web Demo: https:\u002F\u002Fjosephrocca.github.io\u002Frwkv-v4-web\u002Fdemo\u002F (note: only greedy sampling for now)\n\nFor the old RWKV-2: see the release here for a 27M params model on enwik8 with 0.72 BPC(dev). Run run.py in https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v2-RNN. You can even run it in your browser: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FAI-Writer\u002Ftree\u002Fmain\u002Fdocs\u002Feng https:\u002F\u002Fblinkdl.github.io\u002FAI-Writer\u002Feng\u002F (this is using tf.js WASM single-thread mode).\n\n### Training \u002F Fine-tuning\n\npip install deepspeed==0.7.0 \u002F\u002F pip install pytorch-lightning==1.9.5 \u002F\u002F torch 1.13.1+cu117\n\nNOTE: add weight decay (0.1 or 0.01) and dropout (0.1 or 0.01) when training on small amt of data. try x=x+dropout(att(x)) x=x+dropout(ffn(x)) x=dropout(x+att(x)) x=dropout(x+ffn(x)) etc.\n\n**Training RWKV-4 from scratch:** run train.py, which by default is using the enwik8 dataset (unzip https:\u002F\u002Fdata.deepai.org\u002Fenwik8.zip).\n\nYou will be training the \"GPT\" version because it's paralleziable and faster to train. RWKV-4 can extrapolate, so training with ctxLen 1024 can work for ctxLen of 2500+. You can fine-tune the model with longer ctxLen and it can quickly adapt to longer ctxLens.\n\n**Fine-tuning RWKV-4 Pile models:** use 'prepare-data.py' in https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-v2-RNN-Pile\u002Ftree\u002Fmain\u002FRWKV-v3 to tokenize .txt into train.npy data. Then use https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v4neo\u002Ftrain.py to train it.\n\nRead the inference code in src\u002Fmodel.py and try using the final hidden state（.xx .aa .bb) as a faithful sentence embedding for other tasks. Probably you should begin with .xx and .aa\u002F.bb (.aa divided by .bb).\n\nColab for fine-tuning RWKV-4 Pile models: https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fresloved\u002FRWKV-notebooks\u002Fblob\u002Fmaster\u002FRWKV_v4_RNN_Pile_Fine_Tuning.ipynb\n\n**Large corpus:** Use https:\u002F\u002Fgithub.com\u002FAbel2076\u002Fjson2binidx_tool to convert .jsonl into .bin and .idx\n\nThe jsonl format sample (one line for each document):\n```\n{\"text\": \"This is the first document.\"}\n{\"text\": \"Hello\\nWorld\"}\n{\"text\": \"1+1=2\\n1+2=3\\n2+2=4\"}\n```\ngenerated by code like this:\n```\nss = json.dumps({\"text\": text}, ensure_ascii=False)\nout.write(ss + \"\\n\")\n```\n\n**Infinite ctxlen training (WIP):** https:\u002F\u002Fgithub.com\u002FBlealtan\u002FRWKV-LM-LoRA\u002Ftree\u002Fdev-infctx\n\n### How to use RWKV hidden state as text embedding\n\nConsider RWKV 14B. The state has 200 vectors, that is, 5 vectors for each block: fp16 (xx), fp32 (aa), fp32 (bb), fp32 (pp), fp16 (xx).\n\nDo not avg pool because different vectors (xx aa bb pp xx) in the state have very different meanings and ranges. You can probably remove pp.\n\nI suggest firstly collect the mean+stdev statistics of each channel of each vector, and normalize all of them (note: the normalization should be data-indepedent and collected from various texts). Then train a linear classifer.\n\n## Towards RWKV-5 (just to record some new ideas)\n\n### Lastest Design\n\nRWKV-5 is multi-head and here shows one head. There is also a LayerNorm for each head (hence actually GroupNorm).\n\n$`\n\\begin{array}{|l|l|l|}\n\\hline & \\text { RWKV-4 with real-valued } k \\,\\&\\, v \\,\\&\\, u \\,\\&\\, w & \\text { RWKV-5 with matrix-valued } \\mathrm{k}^{\\dagger} \\mathrm{v} \\,\\&\\, \\mathrm{u} \\,\\&\\, \\mathrm{w} \\\\\n\\hline \\mathrm{y}_0 & \\mathrm{r}_0 \\frac{\\mathrm{uk}_0 \\mathrm{v}_0}{\\mathrm{uk}_0} & \\mathrm{r}_0\\left(\\mathrm{uk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_1 & \\mathrm{r}_1 \\frac{\\mathrm{uk}_1 \\mathrm{v}_1+\\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_1+\\mathrm{k}_0} & \\mathrm{r}_1\\left(\\mathrm{uk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_2 & \\mathrm{r}_2 \\frac{\\mathrm{uk}_2 \\mathrm{v}_2+\\mathrm{k}_1 \\mathrm{v}_1+\\mathrm{wk}_0 \\mathrm{v}_0}{\\mathrm{uk}_2+\\mathrm{k}_1+\\mathrm{wk}_0} & \\mathrm{r}_2\\left(\\mathrm{uk}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{k}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{wk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_3 & \\mathrm{r}_3 \\frac{\\mathrm{uk}_3 \\mathrm{v}_3+\\mathrm{k}_2 \\mathrm{v}_2+\\mathrm{wk}_1 \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_3+\\mathrm{k}_2+\\mathrm{wk}_1+\\mathrm{w}^2 \\mathrm{k}_0} & \\mathrm{r}_3\\left(\\mathrm{uk}_3^{\\dagger} \\mathrm{v}_3+\\mathrm{k}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{wk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline\n\\end{array}`$\n\n$`\\left[\\begin{array}{ll}\n\\mathrm{y}_{20} & \\cdots \\mathrm{y}_{2 \\mathrm{c}}\n\\end{array}\\right]=\\left[\\begin{array}{lll}\n\\mathrm{r}_{20} & \\cdots & \\mathrm{r}_{2 \\mathrm{c}}\n\\end{array}\\right]`$\n$`\\left(\\left[\\begin{array}{ccc}\n\\mathrm{u}_{00} & \\cdots & \\mathrm{u}_{0 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{u}_{\\mathrm{c} 0} & \\cdots & \\mathrm{u}_{\\mathrm{cc}}\n\\end{array}\\right]\\left[\\begin{array}{ccc}\n\\mathrm{k}_{20} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{20} \\mathrm{v}_{2 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{2 \\mathrm{c}}\n\\end{array}\\right]+\\left[\\begin{array}{ccc}\n\\mathrm{k}_{10} \\mathrm{v}_{10} & \\cdots & \\mathrm{k}_{10} \\mathrm{v}_{1 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{1 \\mathrm{c}} \\mathrm{v}_{10} & \\cdots & \\mathrm{k}_{1 \\mathrm{c}} \\mathrm{v}_{1 \\mathrm{c}}\n\\end{array}\\right]+\\left[\\begin{array}{ccc}\n\\mathrm{w}_{00} & \\cdots & \\mathrm{w}_{0 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{w}_{\\mathrm{c} 0} & \\cdots & \\mathrm{w}_{\\mathrm{cc}}\n\\end{array}\\right]\\left[\\begin{array}{ccc}\n\\mathrm{k}_{00} \\mathrm{v}_{00} & \\cdots & \\mathrm{k}_{00} \\mathrm{v}_{0 c} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{0 \\mathrm{c}} \\mathrm{v}_{00} & \\cdots & \\mathrm{k}_{0 \\mathrm{c}} \\mathrm{v}_{0 c}\n\\end{array}\\right]\n\\right)`$\n\n### RWKV-6\n\nDynamic Mix & Dynamic Decay. Example (do this for both TimeMix & ChannelMix):\n```\nTIME_MIX_EXTRA_DIM = 32\nself.time_mix_k_w1 = nn.Parameter(torch.empty(args.n_embd, TIME_MIX_EXTRA_DIM).uniform_(-0.01, 0.01))\nself.time_mix_k_w2 = nn.Parameter(torch.zeros(TIME_MIX_EXTRA_DIM, args.n_embd))\nself.time_mix_v_w1 = nn.Parameter(torch.empty(args.n_embd, TIME_MIX_EXTRA_DIM).uniform_(-0.01, 0.01))\nself.time_mix_v_w2 = nn.Parameter(torch.zeros(TIME_MIX_EXTRA_DIM, args.n_embd))\nself.time_mix_r_w1 = nn.Parameter(torch.empty(args.n_embd, TIME_MIX_EXTRA_DIM).uniform_(-0.01, 0.01))\nself.time_mix_r_w2 = nn.Parameter(torch.zeros(TIME_MIX_EXTRA_DIM, args.n_embd))\nself.time_mix_g_w1 = nn.Parameter(torch.empty(args.n_embd, TIME_MIX_EXTRA_DIM).uniform_(-0.01, 0.01))\nself.time_mix_g_w2 = nn.Parameter(torch.zeros(TIME_MIX_EXTRA_DIM, args.n_embd))\n...\ntime_mix_k = self.time_mix_k.view(1,1,-1) + (x @ self.time_mix_k_w1) @ self.time_mix_k_w2\ntime_mix_v = self.time_mix_v.view(1,1,-1) + (x @ self.time_mix_v_w1) @ self.time_mix_v_w2\ntime_mix_r = self.time_mix_r.view(1,1,-1) + (x @ self.time_mix_r_w1) @ self.time_mix_r_w2\ntime_mix_g = self.time_mix_g.view(1,1,-1) + (x @ self.time_mix_g_w1) @ self.time_mix_g_w2\n\nxx = self.time_shift(x)\nxk = x * time_mix_k + xx * (1 - time_mix_k)\nxv = x * time_mix_v + xx * (1 - time_mix_v)\nxr = x * time_mix_r + xx * (1 - time_mix_r)\nxg = x * time_mix_g + xx * (1 - time_mix_g)\n```\n\n![RWKV-v6](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_2228b0f4be21.png)\n\n### RWKV-7\n\nUse parallelized mode to quickly generate the state, then use a finetuned full RNN (the layers of token n can use outputs of all layer of token n-1) for sequential generation.\n\n### Some old ideas\n\n1. Now time decay is like 0.999^T (0.999 is learnable). Change it to something like (0.999^T + 0.1) where 0.1 is learnable too. The 0.1 part will be kept forever. Or, A^T + B^T + C = fast-decay + slow-decay + constant. Can even use different formulas (for example, K^2 instead of e^K for a decay component, or, without normalization).\n\n2. Use complex-valued decay (so, rotation instead of decay) in some channels.\n\n3. Inject some trainable and extrapolatable positional encoding?\n\n4. Aside from 2d rotation, we can try other Lie groups such as 3d rotation ( SO(3) ). Non-abelian RWKV lol.\n\n5. RWKV might be great on analog devices (search for Analog Matrix-vector multiplication & Photonic Matrix-vector multiplication). The RNN mode is very hardware-friendly (processing-in-memory). Can be a SNN too (https:\u002F\u002Fgithub.com\u002Fridgerchu\u002FSpikeGPT). I wonder if it can be optimized for quantum computation.\n\n6. Trainable initial hidden state (xx aa bb pp xx).\n\n7. Layerwise (or even row\u002Fcolumn-wise, elementwise) LR, and test Lion optimizer.\n\n### Vision Tasks\n\n1. I find it's good to add a 2d pos encoding:\n```\nself.pos_emb_x = nn.Parameter(torch.zeros((1,args.my_pos_emb,args.n_embd)))\nself.pos_emb_y = nn.Parameter(torch.zeros((args.my_pos_emb,1,args.n_embd)))\n...\nx = x + pos_emb_x + pos_emb_y\n```\n\n2. In a BPE langauge model, it's the best to use [tokenShift of 1 token] (you can mix more tokens in a char-level English model). However you can try [tokenShift of N (or N-1) (or N+1) tokens] if the image size is N x N, because that will be like mixing [the token above the current positon (or the token above the to-be-predicted positon)] with [current token]. You can use try different tokenShift styles for \"ATT\" & \"FFN\", or mixing different tokenShift styles - such as mixing [token A] with [token A-1] and [token A-(N-1)] etc.\n\n### Misc\n\nMaybe we can improve memorization by simply repeating the context (I guess 2 times is enough). Example:  Reference -> Reference(again) -> Question -> Answer\n\n#### Idea: Bytes-aware Embedding\n\nThe idea is to make sure each token in vocab understand its length and raw UTF-8 bytes.\n\nLet a = max(len(token)) for all token in vocab. Define AA : float[a][d_emb]\n\nLet b = max(len_in_utf8_bytes(token)) for all token in vocab. Define BB : float[b][256][d_emb]\n\nFor each token X in vocab, let [x0, x1, ..., xn] be its raw UTF-8 bytes. We will add some extra values to its embedding EMB(X):\n\nEMB(X) += AA[len(X)] + BB[0][x0] + BB[1][x1] + ... + BB[n][xn] (note: AA BB are learnable weights)\n\n* We can do this for the final Linear(d_emb, n_vocab) projection too.\n* We can use some small networks to generate AA and BB, for some extra regularization (for example, BB[m][xi] and BB[n][xi] should be related).\n\n#### Old Idea\n\nI have an idea to improve tokenization. We can hardcode some channels to have meanings. Example:\n\nChannel 0 = \"space\"\n\nChannel 1 = \"capitalize first letter\"\n\nChannel 2 = \"capitalize all letters\"\n\nTherefore:\n\nEmbedding of \"abc\":  [0, 0, 0, x0, x1, x2 , ..]\n\nEmbedding of \" abc\":  [1, 0, 0, x0, x1, x2, ..]\n\nEmbedding of \" Abc\":  [1, 1, 0, x0, x1, x2, ..]\n\nEmbedding of \"ABC\": [0, 0, 1, x0, x1, x2, ...]\n\n......\n\nso they will share most of the embedding. And we can rapidly compute the output probability of all variations of \"abc\".\n\nNote: the above method is assuming that p(\" xyz\") \u002F p(\"xyz\") is the same for any \"xyz\", which can be wrong.\n\nBetter: define emb_space emb_capitalize_first emb_capitalize_all to be a function of emb.\n\nMaybe the Best: let 'abc' ' abc' etc. to share the last 90% of their embeddings.\n\nAt this moment, all our tokenizers spend too many items to represent all variations of 'abc' ' abc' ' Abc' etc. Moreover the model cannot discover that these are actually similar if some of these variations are rare in the dataset. The method here can improve this. I plan to test this in a new version of RWKV.\n\n#### Idea: Better Initial States\n\nExample (single-round Q & A):\n\n1. Generate the final state of all wiki documents.\n\n2. For any user Q, find the best wiki document, and use its final state as the initial state.\n\n3. Train a model to directly generate the optimal initial state for any user Q.\n\nHowever this can be a bit more tricky for multi-round Q & A :)\n\n## How it works\n\nRWKV is inspired by Apple's AFT (https:\u002F\u002Farxiv.org\u002Fabs\u002F2105.14103).\n\nMoreover it's using a number of my tricks, such as:\n\n* SmallInitEmb: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FSmallInitEmb (applicable to all transformers) which helps the embedding quality, and stabilizes Post-LN (which is what I am using).\n\n* Token-shift: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM#token-shift-time-shift-mixing (applicable to all transformers), especially helpful for char-level models.\n\n* Head-QK: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM#the-head-qk-trick-learning-to-copy-and-avoid-tokens (applicable to all transformers). Note: it's helpful, but I disabled it in the Pile model to keep it 100% RNN.\n\n* Extra R-gate in the FFN (applicable to all transformers). I am also using reluSquared from Primer.\n\n* Better initilization: I init most of the matrices to ZERO (see RWKV_Init in https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v2-RNN\u002Fsrc\u002Fmodel.py).\n\n* You can transfer some parameters from a small model to a large model (note: I sort & smooth them too), for faster and better convergence (see https:\u002F\u002Fwww.reddit.com\u002Fr\u002FMachineLearning\u002Fcomments\u002Fumq908\u002Fr_rwkvv2rnn_a_parallelizable_rnn_with\u002F).\n\n* My CUDA kernel: https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-CUDA to speedup training.\n\n## The pseudocode (execution from top to bottom):\n\n![RWKV-v2-RNN](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_02009191186b.png)\n\nThe a b c d factors work together to build a time-decay curve: [X, 1, W, W^2, W^3, ...].\n\nWrite out the formulas for \"token at pos 2\" and \"token at pos 3\" and you will get the idea:\n* a and b: EMAs of kv and k.\n* c and d: these are a and b combined with \"self-attention\".\n\nkv \u002F k is the memory mechanism. The token with high k can be remembered for a long duration, if W is close to 1 in the channel.\n\nThe R-gate is important for performance. k = info strength of this token (to be passed to future tokens). r = whether to apply the info to this token.\n\n## RWKV-3 improvements\n\nUse different trainable TimeMix factors for R \u002F K \u002F V in SA and FF layers. Example:\n```python\nxx = self.time_shift(x)\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxv = x * self.time_mix_v + xx * (1 - self.time_mix_v)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n```\n\nUse preLN instead of postLN (more stable & faster convergence):\n```python\nif self.layer_id == 0:\n\tx = self.ln0(x)\nx = x + self.att(self.ln1(x))\nx = x + self.ffn(self.ln2(x))\n```\n\n## Explaining the code for RWKV-3 GPT mode\n\n### The GPT mode - overview\n\nThe building blocks of RWKV-3 GPT mode are similar to that of a usual preLN GPT.\n\nThe only difference is an extra LN after embedding. Note you can absorb this LN into the embedding after finishing the training.\n```python\nx = self.emb(idx)  # input: idx = token indices\nx = self.ln_emb(x) # extra LN after embedding\nx = x + self.att_0(self.ln_att_0(x)) # preLN\nx = x + self.ffn_0(self.ln_ffn_0(x))\n...\nx = x + self.att_n(self.ln_att_n(x))\nx = x + self.ffn_n(self.ln_ffn_n(x))\nx = self.ln_head(x) # final LN before projection\nx = self.head(x)    # output: x = logits\n```\nIt is important to initialize emb to tiny values, such as nn.init.uniform_(a=-1e-4, b=1e-4), to utilize my trick https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FSmallInitEmb.\n\nFor the 1.5B RWKV-3, I use Adam (no wd, no dropout) optimizer on 8 * A100 40G.\n\nbatchSz = 32 * 896, ctxLen = 896. I am using tf32 so the batchSz is a bit small. \n\nFor the first 15B tokens, LR is fixed at 3e-4, and beta=(0.9, 0.99).\n\nThen I set beta=(0.9, 0.999), and do an exponential decay of LR, reaching 1e-5 at 332B tokens.\n\n### The GPT mode - ATT block\n\nThe RWKV-3 does not have any attention in the usual sense, but we will call this block ATT anyway.\n```python\nB, T, C = x.size() # x = (Batch,Time,Channel)\n\n# Mix x with the previous timestep to produce xk, xv, xr\nxx = self.time_shift(x) # self.time_shift = nn.ZeroPad2d((0,0,1,-1))\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxv = x * self.time_mix_v + xx * (1 - self.time_mix_v)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n\n# Use xk, xv, xr to produce k, v, r\nk = self.key(xk).transpose(-1, -2)\nv = self.value(xv).transpose(-1, -2)\nr = self.receptance(xr)\nk = torch.clamp(k, max=60) # clamp k to avoid overflow\nk = torch.exp(k)\nkv = k * v\n\n# Compute the W-curve = [e^(-n * e^time_decay), e^(-(n-1) * e^time_decay), ..., 1, e^(time_first)]\nself.time_w = torch.cat([torch.exp(self.time_decay) * self.time_curve.to(x.device), self.time_first], dim=-1)\nw = torch.exp(self.time_w)\n\n# Use W to mix kv and k respectively. Add K_EPS to wk to avoid divide-by-zero\nif RUN_DEVICE == 'cuda':\n    wkv = TimeX.apply(w, kv, B,C,T, 0)\n    wk = TimeX.apply(w, k, B,C,T, K_EPS)\nelse:\n    w = w[:,-T:].unsqueeze(1)\n    wkv = F.conv1d(nn.ZeroPad2d((T-1, 0, 0, 0))(kv), w, groups=C)\n    wk = F.conv1d(nn.ZeroPad2d((T-1, 0, 0, 0))(k), w, groups=C) + K_EPS\n\n# The RWKV formula\nrwkv = torch.sigmoid(r) * (wkv \u002F wk).transpose(-1, -2)\nrwkv = self.output(rwkv) # final output projection\n```\n\nThe self.key, self.receptance, self.output matrices are all initialized to zero.\n\nThe time_mix, time_decay, time_first vectors are transferred from a smaller trained model (note: I sort & smooth them too).\n\n### The GPT mode - FFN block\n\nThe FFN block has three tricks comparing with the usual GPT:\n\n1. My time_mix trick.\n\n2. The sqReLU from the Primer paper.\n\n3. An extra receptance-gate (similar to the receptance-gate in ATT block).\n```python\n# Mix x with the previous timestep to produce xk, xr\nxx = self.time_shift(x)\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n\n# The usual FFN operation\nk = self.key(xk)\nk = torch.square(torch.relu(k)) # from the Primer paper\nkv = self.value(k)\n\n# Apply an extra receptance-gate to kv\nrkv = torch.sigmoid(self.receptance(xr)) * kv\nreturn rkv\n```\nThe self.value, self.receptance matrices are all initialized to zero.\n\n## RWKV-4 improvements\n\n![RWKV-v3-plan](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_5de7ddc9a3e1.png)\n\n## From GPT to RWKV (the formulas)\n\nLet F[t] be the system state at t.\n\nLet x[t] be the new external input at t.\n\nIn GPT, predicting F[t+1] requires considering F[0], F[1], .. F[t]. So it takes O(T^2) to generate a length T sequence.\n\nThe **simplified formula** for GPT:\n\n![F[\\mathrm{t}+1]=\\frac{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}]) \\cdot(\\mathbf{V}F[\\mathrm{i}])}{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B%5Cmathrm%7Bt%7D%2B1%5D%3D%5Cfrac%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D)\n\nIt's very capable in theory, however that **does not mean we can fully utilize its capability with usual optimizers**. I suspect the loss landscape is too difficult for our current methods.\n\nCompare with the **simplified formula** for RWKV (the parallel mode, looks similar to Apple's AFT):\n\n![F[\\mathrm{t}+1]=\\sigma(\\mathbf{R}x[\\mathrm{t}]) \\cdot \\frac{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K}F[\\mathrm{i}]) \\cdot(\\mathbf{V}F[\\mathrm{i}])}{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K }F[\\mathrm{i}])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B%5Cmathrm%7Bt%7D%2B1%5D%3D%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot+%5Cfrac%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D)\n\nThe R, K, V are trainable matrices, and W is a trainable vector (time-decay factor for each channel).\n\nIn GPT, the contribution of F[i] to F[t+1] is weighted by ![ \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}]) ](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle++%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+).\n\nIn RWKV-2, the contribution of F[i] to F[t+1] is weighted by ![\\sigma(\\mathbf{R}x[\\mathrm{t}]) \\cdot \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K}F[\\mathrm{i}]) ](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+).\n* The ![\\sigma](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma) is a non-linearity and we can use sigmoid. \n* Note ![\\sigma(\\mathbf{R}x[\\mathrm{t}])](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29) is not in the denominator, and I call R the \"receptance\".\n* The ![\\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i}))](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29) is the time-decay factor. I proposed the same idea (scaling the attention by distance) in Aug 2020 and called it the \"time-weighting\" (check the commit history of https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FminGPT-tuned).\n\nHere comes the punchline: we can rewrite it into a RNN (recursive formula). Note:\n\n![F[1]=\\sigma(\\mathbf{R }x[0]) \\cdot \\frac{ \\exp (\\mathbf{K }F[0]) \\cdot(\\mathbf{V }F[0])}{\\exp (\\mathbf{K }F[0])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B1%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5B0%5D%29+%5Ccdot+%5Cfrac%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B0%5D%29%7D%7B%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29%7D)\n\n![F[2]=\\sigma(\\mathbf{R }x[1]) \\cdot \\frac{ \\exp (\\mathbf{K }F[1]) \\cdot(\\mathbf{V }F[1])+\\exp (\\mathbf{W} ) \\cdot \\exp (\\mathbf{K }F[0]) \\cdot(\\mathbf{V }F[0])}{ \\exp (\\mathbf{K }F[1])+\\exp (\\mathbf{W} ) \\cdot \\exp (\\mathbf{K }F[0])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B2%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5B1%5D%29+%5Ccdot+%5Cfrac%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B1%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B1%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B0%5D%29%7D%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B1%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29%7D)\n\nTherefore it's straightforward to verify:\n\n![F[t+1]=\\sigma(\\mathbf{R }x[t]) \\cdot \\frac{\\exp (\\mathbf{K}F[\\mathrm{t}]) \\cdot(\\mathbf{V}F[\\mathrm{t}])+\\exp (\\mathbf{W}) \\cdot A[\\mathrm{t}]}{ \\exp (\\mathbf{K}F[\\mathrm{t}])+\\exp (\\mathbf{W}) \\cdot B[\\mathrm{t}]}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5Bt%2B1%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5Bt%5D%29+%5Ccdot+%5Cfrac%7B%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bt%7D%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D%29+%5Ccdot+A%5B%5Cmathrm%7Bt%7D%5D%7D%7B+%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bt%7D%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D%29+%5Ccdot+B%5B%5Cmathrm%7Bt%7D%5D%7D)\n\nwhere A[t] and B[t] are the numerator and denominator of the previous step, respectively.\n\nI believe RWKV is performant because W is like repeatedly applying a diagonal matrix. Note (P^{-1} D P)^n = P^{-1} D^n P, so it is similar to repeatedly applying a general diagonalizable matrix.\n\nMoreover it's possible to turn it into a continuous ODE (a bit similar to State Space Models). I will write about it later.\n\n## Star History\n\n[![Star History Chart](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_8b30a909dab8.png)](https:\u002F\u002Fstar-history.com\u002F#BlinkDL\u002FRWKV-LM&Date)\n\n## Multimodal ideas\n\nI have an idea for [text --> 32x32 RGB image] using a LM (transformer, RWKV, etc.). Will test it soon.\n\nFirstly, LM loss (instead of L2 loss), so the image will not be blurry.\n\nSecondly, color quantization. For example, only allowing 8 levels for R\u002FG\u002FB. Then the image vocab size is 8x8x8 = 512 (for each pixel), instead of 2^24.\nTherefore, a 32x32 RGB image = a len1024 sequence of vocab512 (image tokens), which is a typical input for usual LMs.\n(Later we can use diffusion models to upsample and generate RGB888 images. We might be able to use a LM for this too.)\n\nThirdly, 2D positional embeddings that are easy for the model to understand.\nFor example, add one-hot X & Y coords to the first 64(=32+32) channels. Say if the pixel is at x=8, y=20, then we will add 1 to channel 8 and channel 52 (=32+20).\nMoreover probably we can add the float X & Y coords (normalized to 0~1 range) to another 2 channels. And other periodic pos. encoding might help too (will test). \n\nFinally, RandRound when doing the color quantization in the DataLoader.\nFor example, if the float level is 4.578, then there is a 57.8% chance to use 5, and (1-57.8%) chance to use 4.\nAnd we can allow both 4 and 5 in the prediction, but the loss will be higher if the prediction is 4.\n\nMulti-task training might help too. I will try this dataset format:\n[TxtFirst] [Desc of Img (txt tokens)] [Img] [img tokens]\nand sometimes\n[ImgFirst] [img tokens] [Txt] [Desc of Img (txt tokens)]\n... the order of the imgs should be randomized in the DataLoader, and [TxtFirst] [ImgFirst] [Img] [Txt] are special tokens\nand do random sampling of the full dataset. So sometimes the model will see the img tokens first and then the corresponding txt tokens, which is a [img -> txt] task. And the model will see some partial imgs and partial txts. I think a char-level LM might help the model to write correct text on images.\n\n## How to sample a large dataset (for training)\n\nI am using a trick to sample the Pile deterministically yet randomly enough.\n\nLet's say the pile has x chunks (a chunk = ctx_len tokens).\n\npick a prime number p just less than x, and make sure p = 2 (mod 3).\n\nUse (step * step * step) mod p to sample it. Add some bias to step for extra randomness.\n\n## The top-p-x sampling method (for inference)\n\nWe propose a new sampling method called top-p-x:\n\nit's like top-p, and the only difference is you also keep all tokens whose prob > x.\n\nTry x = 0.01 first.\n\n## Better Learning Rate Schedule via Variantional Method of Loss Curve\n\nI propose a simple new method to find better LR schedules. The method is cost-efficient and practical for large LMs. The takeaway is we can model the loss curve dynamics (phenomenology) w.r.t. the LR, and a nice closed-form LR curve can be directly computed from it using variantional method. Moreover we can predict the final loss with reasonable accuracy.\n\nUPDATE: In \"Conclusion 1.\", use the best-fitting regime (ignore the initial steps where our approximations break down) to fit the parameters.\n\nTry this: fixed lr for 1 hr, then exponential decay to 0.2 * lr in 12 hrs, and choose the t=[1hr, 13hr] segment.\n\nIn the last three plots, black = predicted loss curve of the new LR schedule, blue = original (unoptimized) real loss curve, orange = new LR schedule.\n\n![better_lr_schedule](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_4ec9545eecee.png)\n\n# RWKV v1\n\nWe propose the RWKV language model, with alternating time-mix and channel-mix layers:\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+%5Cbegin%7Balign%2A%7D%0A%5Ctext%7BTime-mix+%3A%7D+%26%26+%5Ctext%7BTM%7D_%7Bt%2Cc%7D+%26%26%3D%26%26%5Ctext%7Bsigmoid%7D%28%5Ctext%7BR%7D_%7Bt%2Cc%7D%29+%26%26%5Ccdot%26%26+%26%26%5Ctextstyle%5Csum_%7Bu%7D+%26%26%5Ctextbf%7BW%7D_%7Bt%2Cu%2Cc%7D+%26%26%5Ccdot%26%26+%5Ctext%7Bsoftmax%7D_t%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29+%26%26%5Ccdot%26%26+%5Ctext%7BV%7D_%7Bu%2Cc%7D%5C%5C%0A%5Ctext%7BChannel-mix+%3A%7D+%26%26+%5Ctext%7BCM%7D_%7Bt%2Cc%7D+%26%26%3D%26%26%5Ctext%7Bsigmoid%7D%28%5Ctext%7BR%7D_%7Bt%2Cc%7D%29+%26%26%5Ccdot%26%26+%26%26%5Ctextstyle%5Csum_d+%26%26%5Ctextbf%7BW%7D_%7Bc%2Cd%7D+%26%26%5Ccdot%26%26+%5Ctext%7Bgelu%7D%28%5Ctext%7BK%7D_%7Bt%2Cd%7D%29+%26%26%5Ccdot%26%26+%5Ctext%7BV%7D_%7Bt%2Cd%7D%0A%5Cend%7Balign%2A%7D%0A\" \nalt=\"\\begin{align*}\n\\text{Time-mix :} && \\text{TM}_{t,c} &&=&&\\text{sigmoid}(\\text{R}_{t,c}) &&\\cdot&& &&\\textstyle\\sum_{u} &&\\textbf{W}_{t,u,c} &&\\cdot&& \\text{softmax}_t(\\text{K}_{u,c}) &&\\cdot&& \\text{V}_{u,c}\\\\\n\\text{Channel-mix :} && \\text{CM}_{t,c} &&=&&\\text{sigmoid}(\\text{R}_{t,c}) &&\\cdot&& &&\\textstyle\\sum_d &&\\textbf{W}_{c,d} &&\\cdot&& \\text{gelu}(\\text{K}_{t,d}) &&\\cdot&& \\text{V}_{t,d}\n\\end{align*}\n\">\n\n* The R, K, V are generated by linear transforms of input, and W is parameter. The idea of RWKV is to decompose attention into R(target) * W(src, target) * K(src). So we can call R \"receptance\", and sigmoid means it's in 0~1 range.\n\n* The Time-mix is similar to AFT (https:\u002F\u002Farxiv.org\u002Fabs\u002F2105.14103). There are two differences.\n\n(1) We changed the normalization (denominator). For masked language models, we define:\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+%5Ctext%7Bsoftmax%7D_t%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29+%3D+%5Cfrac%7B%5Cexp%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29%7D%7B%5Csum_%7Bv+%5Cleq+t%7D%5Cexp%28%5Ctext%7BK%7D_%7Bv%2Cc%7D%29%7D\" \nalt=\"\\text{softmax}_t(\\text{K}_{u,c}) = \\frac{\\exp(\\text{K}_{u,c})}{\\sum_{v \\leq t}\\exp(\\text{K}_{v,c})}\">\n\n**(UPDATE: We are using the original AFT normalization in v2)**\n \nInitialize K and R matrices (and the output projection matrix) to ZERO for fast & stable convergence.\n \n(2) We decompose W_{t,u,c} and introduce multi-head W (here h is the corresponding head of c):\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+W_%7Bt%2Cu%2Cc%7D%3Df_h%28t-u%29%5Ccdot+%5Calpha_h%28u%29+%5Ccdot+%5Cbeta_h%28t%29\" \nalt=\"W_{t,u,c}=f_h(t-u)\\cdot \\alpha_h(u) \\cdot \\beta_h(t)\">\n\nMoreover we multiply the final output of Time-mix layer by γ(t). The reason for the α β γ factors, is because the context size is smaller when t is small, and this can be compensated using the α β γ factors.\n\n**(UPDATE: We remove α β γ factors in v2-RNN and restrict W to be of a simple form and hence able to rewrite it as RNN)**\n\n* The Channel-mix is similar to GeGLU (https:\u002F\u002Farxiv.org\u002Fabs\u002F2002.05202) with an extra R factor. Initialize R and W matrices to ZERO for fast & stable convergence.\n\n* Finally, we add extra token-shift (time-shift mixing) as in (https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FminGPT-tuned).\n\n# Token-shift (time-shift mixing)\n\nThe token-shift explicitly uses (half the channels of this token) & (half the channels of prev token) to generate all vectors (QKV, RWKV, ...).\n\n```\nself.time_shift = nn.ZeroPad2d((0,0,1,-1))\n\nx = torch.cat([self.time_shift(x[:, :, :C\u002F\u002F2]), x[:, :, C\u002F\u002F2:]], dim = -1)\n```\n\nDividing channels by 2 and shift-1 works great for char-level English and char-level Chinese LM.\n\nHowever for BPE-level English LM, it's only effective if your embedding is large enough (at least 1024 - so the usual small L12-D768 model is not enough).\n\nMy theory on the effectiveness of token-shift:\n\nWhen we train a GPT, the hidden representation of a token has to accomplish two different objects:\n\n1. Predict the next token. Sometimes this is easy (obvious next token).\n\n2. Collect all previous context info, so later tokens can use it. This is always hard.\n\nThe shifted channels can focus on (2), so we have good propagation of info. It's like some kind of residual connection, or a small RNN inside the transformer.\n\nYou can use token-shift in usual QKV self-attention too. I looked at the weights, and found V really likes the shifted channels, less so for Q. Makes sense if you think about it. I also found you may want to use less mixing in higher layers.\n\np.s. There is a MHA_pro model in this repo with strong performance. Give it a try :)\n\n# The Head-QK Trick: learning to copy and avoid tokens\n\nIn usual transformer, a small model has difficulty copying tokens (such as person names) in the context. We add extra Q & K to the final output such that the model can directly copy (or avoid) tokens in the context. Afterwards the model will teach itself NER (named entity recognition) if you look at the learned weights.\n```\nq = self.head_q(x)[:,:T,:] # projecting to 256-d\nk = self.head_k(x)[:,:T,:] # projecting to 256-d\nc = (q @ k.transpose(-2, -1)) * (1.0 \u002F 256)\nc = c.masked_fill(self.copy_mask[:T,:T] == 0, 0)\nc = c @ F.one_hot(idx, num_classes = self.config.vocab_size).float()       \nx = self.head(x) + c\n```\nNote: when a token occurs multiple times in the context, it might be better to use max(prob) instead of sum(prob).\n\n# The top-a sampling method\n\nWe also propose a new sampling method called top-a (as in src\u002Futils.py):\n\n(1) Find the max probability p_max after softmax.\n\n(2) Remove all entries whose probability is lower than 0.2 * pow(p_max, 2). So it's adaptive, hence \"top-a\".\n\n(3) Feel free to tune the 0.2 and 2 factor. Tune 0.2 first.\n\nThe idea of top-a:\n1. If max_prob=0.9, then remove all tokens with prob \u003C 0.162 (so, removing all alternatives)\n2. If max_prob=0.5, then remove all tokens with prob \u003C 0.05  (so, allowing more choices)\n3. If max_prob=0.1, then remove all tokens with prob \u003C 0.002 (so, allowing lots of possibilities)\n\n```\nprobs = F.softmax(logits, dim=-1)\n\nlimit = torch.pow(torch.max(probs), 2) * 0.02\nlogits[probs \u003C limit] = -float('Inf')\n```\n\n# Performance\n\nCharacter-level loss on simplebooks-92 dataset https:\u002F\u002Fdldata-public.s3.us-east-2.amazonaws.com\u002Fsimplebooks.zip\n\n![RWKV-vs-MHA](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_f17494bae4b0.png)\n\nGray: usual MHA+Rotary+GeGLU - performance not as good. 17.2M params.\n\nRed: RWKV (\"linear\" attention) - VRAM friendly - quite faster when ctx window is long - good performance. 16.6M params.\n\nGreen: MHA+Rotary+GeGLU+Token_shift. 17.2M params.\n\nBlue: MHA_pro (MHA with various tweaks & RWKV-type-FFN) - slow - needs more VRAM - good performance. 16.6M params.\n\n```\n@software{peng_bo_2021_5196578,\n  author       = {PENG Bo},\n  title        = {BlinkDL\u002FRWKV-LM: 0.01},\n  month        = aug,\n  year         = 2021,\n  publisher    = {Zenodo},\n  version      = {0.01},\n  doi          = {10.5281\u002Fzenodo.5196577},\n  url          = {https:\u002F\u002Fdoi.org\u002F10.5281\u002Fzenodo.5196577}\n}\n```\n\n# Initialization\n\nWe use careful initialization for RWKV to get fast convergence - orthogonal matrices with proper scaling, and special time_w curves. Check model.py for details.\n\nSome learned time_w examples:\n\n![RWKV-time-w](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_463461d33ea5.png)\n","# RWKV：可并行化的 RNN，具备 Transformer 级别的 LLM 性能（发音为“RwaKuv”（国际音标：rʌkuv），源自四个主要参数：R W K V）\n\nRWKV 官网：https:\u002F\u002Frwkv.com（包含 150 多篇训练各种 RWKV 模型的论文）\n\nRWKV Twitter：https:\u002F\u002Ftwitter.com\u002FBlinkDL_AI（最新消息）\n\nRWKV Discord：https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc\n\nRWKV-7 “Goose” 是目前地球上最强的 **线性时间** & **常量空间**（无需 kv 缓存）& **无注意力机制** & 100% RNN 架构，适用于 LLM 和多模态应用等（详情请见 [rwkv.com](https:\u002F\u002Frwkv.com)）。\n\nRWKV-7 是一种 [元上下文学习器](https:\u002F\u002Fraw.githubusercontent.com\u002FBlinkDL\u002FRWKV-LM\u002Fmain\u002Fhttps:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_2d63b5cf5e4f.png)，它在推理时通过上下文梯度下降，在每个 token 处更新其状态。\n\nRWKV 是 [Linux 基金会 AI 项目](https:\u002F\u002Flfaidata.foundation\u002Fprojects\u002Frwkv\u002F)，因此完全免费。RWKV 运行时已集成到 Windows 和 Office 中（[推特链接](https:\u002F\u002Fx.com\u002FBlinkDL_AI\u002Fstatus\u002F1831012419508019550)）。\n\n欢迎向 RWKV 社区（如 [RWKV Discord](https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc)）咨询，了解如何将您的注意力机制或 SSM 模型升级至 RWKV7 模型 :)\n\n---\n\nRWKV 聊天：https:\u002F\u002Frwkv.halowang.cloud\u002F（适用于手机和桌面的本地推理）以及 https:\u002F\u002Fgithub.com\u002FRWKV-APP\u002FRWKV_APP\n\n最新的 RWKV 权重：https:\u002F\u002Fhuggingface.co\u002FBlinkDL\n\nGGUF 格式：https:\u002F\u002Fhuggingface.co\u002Fcollections\u002Fshoumenchougou\u002Frwkv7-gxx-gguf\n\n高效推理：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FAlbatross\n* 在 RTX 5090 上，RWKV-7 7.2B 模型以 fp16 精度、bsz1 设置解码时，速度可达 145+ tokens\u002Fs（始终保持恒定的速度和显存占用）\n* 在 RTX 5090 上，RWKV-7 7.2B 模型以 fp16 精度、bsz960 设置解码时，速度可达 10250+ tokens\u002Fs（始终保持恒定的速度和显存占用）\n* 在 RTX 5090 上，RWKV-7 7.2B 模型以 fp16 精度、bsz320 设置解码时，速度可达 9650+ tokens\u002Fs（始终保持恒定的速度和显存占用）\n* 在 RTX 5090 上，RWKV-7 7.2B 模型以 fp16 精度、bsz1 设置预填充时，速度可达 11289 tokens\u002Fs（始终保持恒定的速度和显存占用）\n\n移动端推理库：https:\u002F\u002Fgithub.com\u002FMollySophia\u002Frwkv-mobile\n\n---\n\n快速 RWKV-7 CUDA 内核（基础版、状态调优版、状态传递版）：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-CUDA\u002Ftree\u002Fmain\u002Frwkv7_fast_fused\n\n我目前的 RWKV7 内核在 0.1\u002F0.4B 规模上比优化后的 Transformer 慢 2 倍，但使用 7B+ 规模时可以达到不错的速度。RWKV7 7.2B 模型在 4x8xH100 GPU 上，ctx8192、zero2+cp 设置下训练时，速度可达 206k tokens\u002Fs。\n\n**请使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v7\u002Ftrain_temp 作为 RWKV-7 的参考实现**。默认配置仅需 1 张拥有 10G 显存的 GPU（如果您显存较少，可以适当降低 batch size），因此非常容易测试。\n\n简化版 RWKV-7 训练示例：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Ftrain_temp\u002Frwkv7_train_simplified.py\n\n**重要提示**（均在 rwkv7_train_simplified.py 中体现）：\n* RWKV 应使用 PreLN LayerNorm（而非 RMSNorm）。我认为这与更好的初始状态有关，因为我并未使用可训练的初始状态（发现使用 LayerNorm 时，初始状态并无助益）。\n* 只对模型中的大型矩阵参数（基本上是投影层）应用权重衰减，而非对所有参数都进行衰减。这一点非常重要。\n* 使用正确的初始化方法。\n\n请注意，FLA RWKV-7 目前尚未与参考实现对齐，因此性能会有所下降。\n\n这是因为 RWKV-7 是一个整体模型，各项设置都非常精细，包括为不同参数采用不同的初始化、权重衰减和学习率等，因此它具有良好的可扩展性和极高的稳定性（无波动）。\n\n但相应的代价是，并不存在一个简单的“RWKV-7 层”，因为 PyTorch 的单个层无法确保自身使用正确的初始化和超参数。\n\n因此，如果您需要将 RWKV-7 应用于其他任务，请仔细研究 train_temp 代码（仅几百行），并根据需求进行修改。\n\n更多信息请参阅：https:\u002F\u002Fgithub.com\u002FYS-Tang\u002FRWKV-FLA-comparison\n\n\u003Cimg width=\"3318\" height=\"2475\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_9f213610230e.png\" \u002F>\n\n\u003Cimg width=\"2656\" height=\"1956\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_61ff79c925f0.png\" \u002F>\n\n===\n\nRWKV-8：\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_93d323fcd470.png\">\n\n改进 RNN：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-8.md\n\n===\n\nRWKV 发展历程（从 v1 到 v7）：[https:\u002F\u002Fwiki.rwkv.com](https:\u002F\u002Fwiki.rwkv.com\u002F)（注：由 AI 生成，可能存在错误）\n\nGradio 示例 1：https:\u002F\u002Fhuggingface.co\u002Fspaces\u002FBlinkDL\u002FRWKV-Gradio-1\n\nGradio 示例 2：https:\u002F\u002Fhuggingface.co\u002Fspaces\u002FBlinkDL\u002FRWKV-Gradio-2\n\nWebGPU 示例：https:\u002F\u002Fcryscan.github.io\u002Fweb-rwkv-puzzles\u002F#\u002Fchat\n\n===\n\nRWKV-Runner GUI：https:\u002F\u002Fgithub.com\u002FjosStorer\u002FRWKV-Runner\u002Freleases\n\nAi00 服务器：https:\u002F\u002Fgithub.com\u002FAi00-X\u002Fai00_server\n\nRWKV pip 包：https:\u002F\u002Fpypi.org\u002Fproject\u002Frwkv\u002F\n\nPEFT（LoRA 等）：https:\u002F\u002Fgithub.com\u002FJL-er\u002FRWKV-PEFT\n\nRLHF：https:\u002F\u002Fgithub.com\u002FOpenMOSE\u002FRWKV-LM-RLHF\n\n超过 400 个 RWKV 项目：https:\u002F\u002Fgithub.com\u002Fsearch?o=desc&q=rwkv&s=updated&type=Repositories\n\n**更快的 RWKV-7 内核**：https:\u002F\u002Fgithub.com\u002Fjohanwind\u002Fwind_rwkv\n\n===\n\nRWKV-5\u002F6 Eagle\u002FFinch 论文：https:\u002F\u002Farxiv.org\u002Fabs\u002F2404.05892\n\n聊天演示代码：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FAPI_DEMO_CHAT.py\n\n**RWKV-7 演示代码**：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v7\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo.py（类似 GPT 的模式）\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo_rnn.py（RNN 模式）\n\nhttps:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v7\u002Frwkv_v7_demo_fast.py（双模式，速度最快）\n\nRWKV-6 演示代码：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Frwkv_v6_demo.py\n\nRWKV-6 演示代码：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n## 如何在 MiniPile 数据集（1.5G tokens）上训练 RWKV-7\u002F6\u002F5 ##\n\n建议使用 Python 3.10+、PyTorch 2.5+、CUDA 12.4+、最新版本的 DeepSpeed，但务必保持 `pytorch-lightning==1.9.5`。\n\n**训练 RWKV-7**：\n```\n# 可以使用最新版 PyTorch 和 CUDA（不限于 cu121）\npip install torch --upgrade --extra-index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu121\npip install pytorch-lightning==1.9.5 deepspeed wandb ninja --upgrade\n\n# 进入 RWKV-v7 的 train_temp 目录进行训练\ncd RWKV-v7\u002Ftrain_temp\u002F\n\n# 首先下载 MiniPile 的 .bin 和 .idx 文件到 train_temp\u002Fdata 目录（请参考 demo-training-prepare.sh 脚本）\n# 这将生成初始权重文件 rwkv-init.pth，位于 out\u002F......\u002F 目录中\nsh .\u002Fdemo-training-prepare.sh\n\n# 这将加载 rwkv-init.pth 并训练模型。你可能需要先登录 wandb\nsh .\u002Fdemo-training-run.sh\n\n你的 out\u002F......\u002Ftrain_log.txt 文件中应该会有类似如下的损失值：\n0 4.875856 131.0863 0.00059975 2025-04-24 02:23:42.481256 0\n1 4.028621 56.1834 0.00059899 2025-04-24 02:28:16.674463 1\n2 3.801625 44.7739 0.00059773 2025-04-24 02:32:51.059568 2\n3 3.663070 38.9808 0.00059597 2025-04-24 02:37:25.409892 3\n4 3.578974 35.8368 0.00059371 2025-04-24 02:41:59.711315 4\n5 3.510906 33.4786 0.00059096 2025-04-24 02:46:33.990839 5\n6 3.462345 31.8917 0.00058771 2025-04-24 02:51:08.378331 6\n7 3.412196 30.3318 0.00058399 2025-04-24 02:55:42.927474 7\n8 3.376724 29.2747 0.00057978 2025-04-24 03:00:17.504665 8\n9 3.336911 28.1321 0.00057511 2025-04-24 03:04:52.006063 9\n10 3.313411 27.4787 0.00056999 2025-04-24 03:09:27.563336 10\n11 3.295895 27.0016 0.00056441 2025-04-24 03:14:01.786079 11\n```\n\nRWKV-7 1.5B 参数量（L24-D2048，词汇表大小 65536）的权重示例：\n\n**请务必仅对大型张量应用权重衰减（注释中标有“wdecay”的部分）**，否则性能会大幅下降。\n\n| 名称                | 形状         | 注释      | 初始化  |\n|---------------------|---------------|--------------|-----------------|\n| emb.weight          | [65536, 2048] | wdecay       | 参见代码        |\n| blocks.0.ln0.weight | [2048]        | 第 0 层    | 1               |\n| blocks.0.ln0.bias   | [2048]        | 第 0 层    | 0               |\n|                     |               |              |                 |\n| blocks.*.ln1.weight | [2048]        |              | 1               |\n| blocks.*.ln1.bias   | [2048]        |              | 0               |\n| blocks.*.att.x_r    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.x_w    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.x_k    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.x_v    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.x_a    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.x_g    | [1, 1, 2048]  |              | 参见代码        |\n| blocks.*.att.w0     | [1, 1, 2048]  | 学习率加倍  | 参见代码        |\n| blocks.*.att.w1     | [2048, 96]    |              | 0               |\n| blocks.*.att.w2     | [96, 2048]    |              | 参见代码        |\n| blocks.*.att.a0     | [1, 1, 2048]  |              | 0               |\n| blocks.*.att.a1     | [2048, 96]    |              | 0               |\n| blocks.*.att.a2     | [96, 2048]    |              | 参见代码        |\n| blocks.*.att.v0     | [1, 1, 2048]  | 第 1 层及以上 | 1               |\n| blocks.*.att.v1     | [2048, 64]    | 第 1 层及以上 | 0               |\n| blocks.*.att.v2     | [64, 2048]    | 第 1 层及以上 | 参见代码        |\n| blocks.*.att.g1     | [2048, 256]   |              | 0               |\n| blocks.*.att.g2     | [256, 2048]   |              | 参见代码        |\n| blocks.*.att.k_k    | [1, 1, 2048]  |              | 1               |\n| blocks.*.att.k_a    | [1, 1, 2048]  |              | 1               |\n| blocks.*.att.r_k    | [32, 64]      |              | 0               |\n| blocks.*.att.receptance.weight | [2048, 2048] | wdecay       | 参见代码        |\n| blocks.*.att.key.weight        | [2048, 2048] | wdecay       | 参见代码        |\n| blocks.*.att.value.weight      | [2048, 2048] | wdecay       | 参见代码        |\n| blocks.*.att.output.weight     | [2048, 2048] | wdecay       | 0               |\n| blocks.*.att.ln_x.weight       | [2048]       |              | 参见代码        |\n| blocks.*.att.ln_x.bias         | [2048]       |              | 0               |\n|                                |              |              |           |\n| blocks.*.ln2.weight            | [2048]       |              | 1               |\n| blocks.*.ln2.bias              | [2048]       |              | 0               |\n| blocks.*.ffn.x_k               | [1, 1, 2048] |              | 参见代码        |\n| blocks.*.ffn.key.weight        | [8192, 2048] | wdecay       | 参见代码        |\n| blocks.*.ffn.value.weight      | [2048, 8192] | wdecay       | 0               |\n|                                |              |              |           |\n| ln_out.weight | [2048]        |        | 1               |\n| ln_out.bias   | [2048]        |        | 0               |\n| head.weight   | [65536, 2048] | wdecay | 参见代码        |\n\n训练 RWKV-6：使用 \u002FRWKV-v5\u002F，并在 demo-training-prepare.sh 和 demo-training-run.sh 中使用 --my_testing \"x060\"。\n\n你的损失曲线应该与以下曲线几乎完全一致，波动也应相同（如果你使用相同的批量大小和配置）：\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_f75767ee133e.png\" width=\"500\">\n\n你可以通过 https:\u002F\u002Fpypi.org\u002Fproject\u002Frwkv\u002F 来运行你的模型（使用 \"rwkv_vocab_v20230424\" 代替 \"20B_tokenizer.json\"）。\n\n使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fmake_data.py 从 jsonl 文件准备 binidx 数据，并计算 \"--my_exit_tokens\" 和 \"--magic_prime\"。\n\n使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fcompute_magic_prime.py 来为现有的 binidx 数据计算 \"--my_exit_tokens\" 和 \"--magic_prime\"。\n\n处理大规模数据的更快分词器：https:\u002F\u002Fgithub.com\u002Fcahya-wirawan\u002Fjson2bin、https:\u002F\u002Fgithub.com\u002Fcahya-wirawan\u002Frwkv-tokenizer、https:\u002F\u002Fgithub.com\u002Fm8than\u002FRWKV-World-Tokenizer-CPP。\n\n在 train.py 中，“epoch”指的是“迷你 epoch”（并非真正的 epoch，仅为方便起见），且 1 个迷你 epoch 等于 40320 * ctx_len 个 token。\n\n例如，如果你的 binidx 包含 1498226207 个 token，且 ctxlen=4096，则设置 \"--my_exit_tokens 1498226207\"（这将覆盖 epoch_count），此时 mini-epoch 数量为 1498226207\u002F(40320 * 4096) = 9.07。训练程序将在达到 \"--my_exit_tokens\" 的 token 数后自动退出。将 \"--magic_prime\" 设置为小于 datalen\u002Fctxlen-1（即 1498226207\u002F4096-1 = 365776）的最大 3n+2 型素数，在本例中为 \"--magic_prime 365759\"。\n\n简单方法：准备 SFT jsonl 文件 => 在 make_data.py 中将你的 SFT 数据重复 3 或 4 次。重复次数越多，越容易导致过拟合。\n\n进阶方法：在你的 jsonl 文件中将 SFT 数据重复 3 或 4 次（注意 make_data.py 会随机打乱所有 jsonl 项）=> 向 jsonl 文件中添加一些基础数据（如 slimpajama）=> 然后再在 make_data.py 中只重复 1 次。\n\n**修复训练中的尖峰问题**：请参阅此页面上的“修复 RWKV-6 尖峰”部分。\n\n或者直接使用 RWKV-7（效果更好）。RWKV-7 非常稳定且无尖峰现象（已在 0.1\u002F0.4\u002F1.5\u002F2.9b 参数量上验证）：\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_e49feae0927a.png\" width=\"500\">\n\n**RWKV-6 的简单推理**：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n**RWKV-5 的简单推理**：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v5_demo.py\n\n**注意：在 [state = kv + w * state] 中，所有数值都必须以 fp32 格式表示，因为 w 可能非常接近 1。因此，我们可以将 state 和 w 保持为 fp32，而将 kv 转换为 fp32。**\n\nlm_eval：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002Frun_lm_eval.py\n\n**小模型\u002F小数据的技巧**：当我训练 RWKV 音乐模型时，我会使用更深更窄的维度（如 L29-D512），并应用权重衰减和 dropout（如 wd=2，dropout=0.02）。请注意，RWKV-LM 的 dropout 效果非常好，只需使用平时值的四分之一即可。\n\n## 如何在 Pile 数据集（332G 个 token）上训练 RWKV-7 ##\n\n请参阅：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fdemo-training-prepare-v7-pile.sh 和 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fdemo-training-run-v7-pile.sh\n\n首先获取以下文件：\n\npile_20B_tokenizer_text_document.bin (664230651068 字节)\n\npile_20B_tokenizer_text_document.idx (4212099722 字节)\n\n### 如何微调 RWKV-5 模型 ###\n\n请使用 .jsonl 格式准备您的数据（格式可参考：https:\u002F\u002Fhuggingface.co\u002FBlinkDL\u002Frwkv-5-world）。\n\n使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v5\u002Fmake_data.py 脚本，通过 World 分词器将其转换为 binidx 格式，以便用于微调 World 模型。\n\n将您模型文件夹中的基础检查点重命名为 rwkv-init.pth，并调整训练命令如下：对于 7B 参数量的模型，使用 --n_layer 32 --n_embd 4096 --vocab_size 65536 --lr_init 1e-5 --lr_final 1e-5。\n\n0.1B = --n_layer 12 --n_embd 768 \u002F\u002F 0.4B = --n_layer 24 --n_embd 1024 \u002F\u002F 1.5B = --n_layer 24 --n_embd 2048 \u002F\u002F 3B = --n_layer 32 --n_embd 2560 \u002F\u002F 7B = --n_layer 32 --n_embd 4096\n\n### 状态微调（微调初始状态，推理开销为零）\n\n目前实现尚未优化，显存占用与完整 SFT 相同。\n\n```--train_type \"states\" --load_partial 1 --lr_init 1 --lr_final 0.01 --warmup_steps 10（是的，使用非常高的学习率）```\n\n使用 rwkv 0.8.26+ 自动加载训练好的“time_state”。\n\n### 初始化 RWKV 5\u002F6 模型 ###\n\n从头开始训练 RWKV 时，建议使用我的初始化方法以获得最佳性能。请参考 src\u002Fmodel.py 中的 generate_init_weight() 函数：\n```\nemb.weight => nn.init.uniform_(a=-1e-4, b=1e-4)\n（注意，block0 的 ln0 是 emb.weight 的层归一化）\nhead.weight => nn.init.orthogonal_(gain=0.5*sqrt(n_vocab \u002F n_embd))\n\natt.receptance.weight => nn.init.orthogonal_(gain=1)\natt.key.weight => nn.init.orthogonal_(gain=0.1)\natt.value.weight => nn.init.orthogonal_(gain=1)\natt.gate.weight => nn.init.orthogonal_(gain=0.1)\natt.output.weight => 零\n\natt.ln_x.weight（组归一化）=> ((1 + layer_id) \u002F total_layers) ** 0.7\n\nffn.key.weight => nn.init.orthogonal_(gain=1)\nffn.value.weight => 零\nffn.receptance.weight => 零\n```\n!!! 如果您使用位置嵌入，可能最好移除 block.0.ln0，并对 emb.weight 使用默认初始化，而不是我设定的 uniform_(a=-1e-4, b=1e-4) !!!\n\n### 解决 RWKV-6 的尖峰问题 ###\n\n0. 升级到 RWKV-7。它非常稳定。\n\n1. 从零开始训练时，在 “RUN_CUDA_RWKV6(r, k, v, w, u)” 之前添加 “k = k * torch.clamp(w, max=0).exp()”，并记得同时修改推理代码。您会发现收敛速度更快。\n\n2. 使用 “--adam_eps 1e-18”。\n\n3. 如果出现尖峰现象，可以尝试 “--beta2 0.95”。\n\n4. 在 trainer.py 中将学习率调整为 “lr = lr * (0.01 + 0.99 * trainer.global_step \u002F w_step)”（原先是 0.2 + 0.8），并将 “--warmup_steps 20” 改为 20 步。\n\n5. 如果您正在训练大量数据，设置 “--weight_decay 0.1” 可以获得更好的最终损失。此时应将 lr_final 设置为 lr_init 的 1\u002F100。\n\n### 其他信息 ###\n\nRWKV-7 可以进行数学计算。详情请参阅：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FResearch\u002Frwkv7-g0-7.2b.md。\n\n\u003Cimg width=\"555\" height=\"784\" alt=\"image\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_154cc66384ef.png\" \u002F>\n\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_83e9bdbfc056.png\">\n\n## 介绍 RWKV ##\n\nRWKV 是一种兼具 RNN 特性和 Transformer 级别 LLM 性能的模型，同时也可以像 GPT 式的 Transformer 一样直接进行并行化训练。而且它是完全无注意力机制的。您只需要 t 时刻的隐藏状态即可计算 t+1 时刻的状态。您可以使用 “GPT” 模式快速计算出 “RNN” 模式的隐藏状态。\n\n因此，RWKV 结合了 RNN 和 Transformer 的优点——**出色的性能、快速推理、节省显存、快速训练、无限上下文长度以及免费的句子嵌入**（使用最终隐藏状态）。\n\n**所有最新的 RWKV 权重**：https:\u002F\u002Fhuggingface.co\u002FBlinkDL\n\n**兼容 Hugging Face 的 RWKV 权重**：https:\u002F\u002Fhuggingface.co\u002FRWKV\n\n```python\nos.environ[\"RWKV_JIT_ON\"] = '1'\nos.environ[\"RWKV_CUDA_ON\"] = '0' # 如果设为 '1'，则使用 CUDA 内核处理序列模式（速度更快）\nfrom rwkv.model import RWKV                         # pip install rwkv\nmodel = RWKV(model='\u002Ffsx\u002FBlinkDL\u002FHF-MODEL\u002Frwkv-4-pile-1b5\u002FRWKV-4-Pile-1B5-20220903-8040', strategy='cuda fp16')\n\nout, state = model.forward([187, 510, 1563, 310, 247], None)   # 使用 20B_tokenizer.json\nprint(out.detach().cpu().numpy())                   # 获取 logits\nout, state = model.forward([187, 510], None)\nout, state = model.forward([1563], state)           # RNN 有状态（如果需要复制，可使用 deepcopy）\nout, state = model.forward([310, 247], state)\nprint(out.detach().cpu().numpy())                   # 结果与上述相同\n```\n\nnanoRWKV：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FnanoRWKV（无需自定义 CUDA 内核即可训练，适用于任何 GPU\u002FCPU）\n\n**精彩的社区 RWKV 项目**：\n\n所有（400 多个）RWKV 项目：https:\u002F\u002Fgithub.com\u002Fsearch?o=desc&q=rwkv&s=updated&type=Repositories\n\nhttps:\u002F\u002Fgithub.com\u002FOpenGVLab\u002FVision-RWKV 视觉 RWKV\n\nhttps:\u002F\u002Fgithub.com\u002Ffeizc\u002FDiffusion-RWKV 扩散 RWKV\n\nhttps:\u002F\u002Fgithub.com\u002Fcgisky1980\u002Fai00_rwkv_server 最快的 WebGPU 推理（支持 NVIDIA\u002FAMD\u002FIntel）\n\nhttps:\u002F\u002Fgithub.com\u002Fcryscan\u002Fweb-rwkv ai00_rwkv_server 的后端\n\nhttps:\u002F\u002Fgithub.com\u002FsaharNooby\u002Frwkv.cpp 快速 CPU\u002FcuBLAS\u002FCLBlast 推理：int4\u002Fint8\u002Ffp16\u002Ffp32\n\nhttps:\u002F\u002Fgithub.com\u002FJL-er\u002FRWKV-PEFT LoRA\u002FPissa\u002FQLoRA\u002FQPissa\u002F状态微调\n\nhttps:\u002F\u002Fgithub.com\u002FRWKV\u002FRWKV-infctx-trainer 无限上下文训练器\n\nhttps:\u002F\u002Fgithub.com\u002Fdaquexian\u002Ffaster-rwkv\n\nhttps:\u002F\u002Fgithub.com\u002Fmlc-ai\u002Fmlc-llm\u002Fpull\u002F1275\n\nhttps:\u002F\u002Fgithub.com\u002FTheRamU\u002FFay\u002Fblob\u002Fmain\u002FREADME_EN.md 基于 RWKV 的数字助手\n\nhttps:\u002F\u002Fgithub.com\u002Fharrisonvanderbyl\u002Frwkv-cpp-cuda 使用 CUDA\u002FAMD\u002FVulkan 的快速 GPU 推理\n\n**250 行内的 RWKV v6**（包含分词器）：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v6_demo.py\n\n**250 行内的 RWKV v5**（包含分词器）：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_v5_demo.py\n\n**150 行内的 RWKV v4**（模型、推理、文本生成）：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FChatRWKV\u002Fblob\u002Fmain\u002FRWKV_in_150_lines.py\n\n**RWKV v4 预印本**：https:\u002F\u002Farxiv.org\u002Fabs\u002F2305.13048\n\n**RWKV v4 介绍及 100 行 Numpy 实现**：https:\u002F\u002Fjohanwind.github.io\u002F2023\u002F03\u002F23\u002Frwkv_overview.html https:\u002F\u002Fjohanwind.github.io\u002F2023\u002F03\u002F23\u002Frwkv_details.html\n\n![RWKV-7](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_2d63b5cf5e4f.png)\n\n![MQAR](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_aa475cbdaa87.png)\n\n![RWKV-paper](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_023bf1f94811.png)\n\nRWKV v6 插图：\n\n![RWKV-v6](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_05ed34639d18.png)\n\n![RWKV-v5-benchmark-1](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_77fd3e0ec9fb.png)\n\n一篇利用 RWKV 的精彩论文（脉冲神经网络）：https:\u002F\u002Fgithub.com\u002Fridgerchu\u002FSpikeGPT\n\n欢迎加入 RWKV Discord 服务器 https:\u002F\u002Fdiscord.gg\u002FbDSBUMeFpc，共同推进相关工作。我们目前拥有充足的算力资源（A100 40Gs，感谢 Stability 和 EleutherAI），如果您有任何有趣的想法，我可以帮助您实现。\n\n![RWKV-eval2](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_aed14114120c.png)\n\nRWKV 在 Pile 数据集中对 10000 篇 ctx4k+ 文档的损失随 token 位置的变化情况。RWKV 1B5-4k 在 ctx1500 之后基本保持平稳，而 3B-4k、7B-4k 和 14B-4k 则存在一定的斜率，且表现越来越好。这打破了 RNN 无法建模长上下文的传统观点。我们可以预测，RWKV 100B 将表现出色，而 RWKV 1T 或许就是我们所需要的全部 :)\n\n![RWKV-ctxlen](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_7efa80a9456d.png)\n\nChatRWKV 使用 RWKV 14B ctx8192：\n\n![RWKV-chat](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_31d8cb55f4f5.png)\n\n我认为 RNN 更适合作为基础模型，原因如下：(1) 对 ASIC 更友好（无需 KV 缓存）。(2) 对强化学习更友好。(3) 我们写作时，大脑的工作方式更接近 RNN。(4) 宇宙本身也像一个 RNN（因为局部性）。而 Transformer 是非局部模型。\n\nRWKV-3 1.5B 在 A40 上（tf32）= 始终为 0.015 秒\u002Ftoken，使用简单的 PyTorch 代码测试（无 CUDA），GPU 利用率为 45%，显存占用 7823M。\n\nGPT2-XL 1.3B 在 A40 上（tf32）= 0.032 秒\u002Ftoken（对于 ctxlen 1000），使用 Hugging Face 的代码测试，GPU 利用率同样为 45%（很有意思），显存占用 9655M。\n\n训练速度：（新训练代码）RWKV-4 14B BF16 ctxlen4096 = 在 8x8 A100 80G 上达到 114K tokens\u002Fs（ZERO2+CP）。（旧训练代码）RWKV-4 1.5B BF16 ctxlen1024 = 在 8xA100 40G 上达到 106K tokens\u002Fs。\n\n我也在进行图像实验（例如：https:\u002F\u002Fhuggingface.co\u002FBlinkDL\u002Fclip-guided-binary-autoencoder），并且 RWKV 将能够实现文本到图像的扩散模型 :) 我的想法是：256x256 RGB 图像 -> 32x32x13bit 隐变量 -> 应用 RWKV 计算每个 32x32 格子的转移概率 -> 假设这些格子相互独立，并利用这些概率进行“扩散”。\n\n训练过程平稳——没有损失峰值！（学习率和批量大小在约 15G 个 token 左右发生变化）\n![RWKV-loss](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_ef419aff7eb2.png)\n\n![RWKV-eval](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_66fbbf6b4556.png)\n\n所有训练好的模型都将开源。推理速度非常快（仅涉及矩阵-向量乘法，没有矩阵-矩阵乘法），即使在 CPU 上也能运行，因此你甚至可以在手机上运行大型语言模型。\n\n其工作原理是：RWKV 将信息汇集到多个通道中，这些通道会随着下一个 token 的到来以不同的速度衰减。一旦理解了这一点，就会发现它非常简单。\n\n**RWKV 可以并行化，因为每个通道的时间衰减是与数据无关的（且可训练的）**。例如，在普通的 RNN 中，你可以将某个通道的时间衰减从 0.8 调整为 0.5（这被称为“门控”），而在 RWKV 中，你只需将信息从 W-0.8 通道转移到 W-0.5 通道，即可达到同样的效果。此外，如果你需要更高的性能，还可以将 RWKV 微调为不可并行化的 RNN（此时可以使用前一个 token 后层的输出）。\n\n![RWKV-formula](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_a80f544a3ba4.png)\n\n以下是我的一些待办事项。让我们一起努力吧 :)\n\n* Hugging Face 集成（请参阅 https:\u002F\u002Fgithub.com\u002Fhuggingface\u002Ftransformers\u002Fissues\u002F17230），以及优化的 CPU、iOS、Android、WASM 和 WebGL 推理。RWKV 是一种 RNN，非常适合边缘设备。让我们实现让手机也能运行大型语言模型的目标。\n\n* 在双向和 MLM 任务，以及图像、音频和视频标记上进行测试。我认为 RWKV 可以通过以下方式支持编码器-解码器架构：对于每个解码器标记，使用 [解码器前一时刻隐藏状态] 和 [编码器最终隐藏状态] 的学习混合表示。这样，所有的解码器标记都可以访问编码器的输出。\n\n* 目前正在训练 RWKV-4a，只增加了一个微小的注意力机制（相比 RWKV-4 只多了几行代码），以进一步提升小型模型在一些困难的零样本任务上的表现（如 LAMBADA）。详情请参见 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fcommit\u002Fa268cd2e40351ee31c30c5f8a5d1266d35b41829\n\n用户反馈：\n> *我目前在相对较小的预训练数据集（约 10GB 文本）上尝试了基于字符的模型，结果非常好——困惑度与训练时间长得多的模型相当。*\n\n> *天哪，RWKV 真的太快了。我从头开始训练它后切换到另一个标签页，回来时它已经在生成看似合理的英语和毛利语单词了。我又去微波炉热了杯咖啡，回来时它已经能生成完全符合语法的句子了。*\n\nSepp Hochreiter 的推文（感谢！）：https:\u002F\u002Ftwitter.com\u002FHochreiterSepp\u002Fstatus\u002F1524270961314484227\n\n你也可以在 EleutherAI Discord 中找到我（BlinkDL）：https:\u002F\u002Fwww.eleuther.ai\u002Fget-involved\u002F\n\n![RWKV-demo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_eda3c01b6f82.png)\n\n\n\n## 快速入门\n\n**重要提示：请使用 deepspeed==0.7.0、pytorch-lightning==1.9.5、torch==1.13.1+cu117 以及 cuda 11.7.1 或 11.7。注意，torch2 + deepspeed 存在奇怪的 bug，会降低模型性能。**\n\n请使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v4neo（最新代码，兼容 v4 版本）。\n\n这里有一个很棒的提示，可用于测试大型语言模型的问答功能。适用于任何模型：（通过最小化 ChatGPT 的困惑度为 RWKV 1.5B 找到）\n```python\nprompt = f'\\nQ & A\\n\\nQuestion:\\n{qq}\\n\\nDetailed Expert Answer:\\n' # 让模型在此之后生成内容\n```\n\n### 推理\n\n**运行 RWKV-4 Pile 模型：** 从 https:\u002F\u002Fhuggingface.co\u002FBlinkDL 下载模型。在 run.py 中设置 TOKEN_MODE = 'pile'，然后运行。即使在 CPU 上也能快速运行（默认模式）。\n\n**RWKV-4 Pile 1.5B 的 Colab 笔记本：** https:\u002F\u002Fcolab.research.google.com\u002Fdrive\u002F1F7tZoPZaWJf1fsCmZ5tjw6sYHiFOYVWM\n\n在浏览器中运行 RWKV-4 Pile 模型（以及 ONNX 版本）：请参阅此问题 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F7\n\nRWKV-4 Web 演示：https:\u002F\u002Fjosephrocca.github.io\u002Frwkv-v4-web\u002Fdemo\u002F（注：目前仅支持贪婪采样）\n\n对于旧版 RWKV-2：请参阅此处发布的 enwik8 数据集上 27M 参数模型，其开发集 BPC 为 0.72。在 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Ftree\u002Fmain\u002FRWKV-v2-RNN 中运行 run.py 即可。你甚至可以在浏览器中运行它：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FAI-Writer\u002Ftree\u002Fmain\u002Fdocs\u002Feng https:\u002F\u002Fblinkdl.github.io\u002FAI-Writer\u002Feng\u002F（这是使用 tf.js WASM 单线程模式）。\n\n### 训练\u002F微调\n\npip install deepspeed==0.7.0 \u002F\u002F pip install pytorch-lightning==1.9.5 \u002F\u002F torch 1.13.1+cu117\n\n注意：在少量数据上训练时，应加入权重衰减（0.1 或 0.01）和 Dropout（0.1 或 0.01）。可以尝试以下组合：x=x+dropout(att(x))、x=x+dropout(ffn(x))、x=dropout(x+att(x))、x=dropout(x+ffn(x)) 等。\n\n**从头开始训练 RWKV-4：** 运行 train.py，默认使用 enwik8 数据集（解压 https:\u002F\u002Fdata.deepai.org\u002Fenwik8.zip）。\n\n您将训练的是“GPT”版本，因为它可以并行化且训练速度更快。RWKV-4 具有外推能力，因此使用 ctxLen 1024 训练的模型也可以很好地处理 ctxLen 为 2500+ 的情况。您可以使用更长的 ctxLen 对模型进行微调，使其快速适应更长的上下文长度。\n\n**微调 RWKV-4 Pile 模型：** 使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-v2-RNN-Pile\u002Ftree\u002Fmain\u002FRWKV-v3 中的 'prepare-data.py' 将 .txt 文件分词并转换为 train.npy 数据。然后使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v4neo\u002Ftrain.py 来训练该模型。\n\n阅读 src\u002Fmodel.py 中的推理代码，并尝试将最终隐藏状态（.xx、.aa、.bb）用作其他任务的忠实句子嵌入。建议从 .xx 和 .aa\u002F.bb 开始（.aa 除以 .bb）。\n\n用于微调 RWKV-4 Pile 模型的 Colab 笔记本：https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fresloved\u002FRWKV-notebooks\u002Fblob\u002Fmaster\u002FRWKV_v4_RNN_Pile_Fine_Tuning.ipynb\n\n**大型语料库：** 使用 https:\u002F\u002Fgithub.com\u002FAbel2076\u002Fjson2binidx_tool 将 .jsonl 文件转换为 .bin 和 .idx 文件。\n\n.jsonl 格式示例（每行为一个文档）：\n```\n{\"text\": \"这是第一篇文档。\"}\n{\"text\": \"你好\\n世界\"}\n{\"text\": \"1+1=2\\n1+2=3\\n2+2=4\"}\n```\n\n可通过如下代码生成：\n```\nss = json.dumps({\"text\": text}, ensure_ascii=False)\nout.write(ss + \"\\n\")\n```\n\n**无限上下文长度训练（开发中）：** https:\u002F\u002Fgithub.com\u002FBlealtan\u002FRWKV-LM-LoRA\u002Ftree\u002Fdev-infctx\n\n### 如何将 RWKV 隐藏状态用作文本嵌入\n\n以 RWKV 14B 为例，其状态包含 200 个向量，即每个块有 5 个向量：fp16（xx）、fp32（aa）、fp32（bb）、fp32（pp）、fp16（xx）。\n\n不要进行平均池化，因为状态中的不同向量（xx、aa、bb、pp、xx）具有非常不同的含义和范围。您可能可以移除 pp。\n\n我建议首先收集每个向量各通道的均值和标准差统计信息，并对它们进行归一化处理（注意：归一化应与数据无关，需从多种文本中收集）。然后训练一个线性分类器。\n\n## 向 RWKV-5 发展（仅记录一些新想法）\n\n### 最新设计\n\nRWKV-5 是多头架构，此处展示的是其中的一个头。每个头还配备了一个 LayerNorm（实际上是 GroupNorm）。\n\n$`\n\\begin{array}{|l|l|l|}\n\\hline & \\text { RWKV-4，使用实数值 } k \\,\\&\\, v \\,\\&\\, u \\,\\&\\, w & \\text { RWKV-5，使用矩阵值 } \\mathrm{k}^{\\dagger} \\mathrm{v} \\,\\&\\, \\mathrm{u} \\,\\&\\, \\mathrm{w} \\\\\n\\hline \\mathrm{y}_0 & \\mathrm{r}_0 \\frac{\\mathrm{uk}_0 \\mathrm{v}_0}{\\mathrm{uk}_0} & \\mathrm{r}_0\\left(\\mathrm{uk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_1 & \\mathrm{r}_1 \\frac{\\mathrm{uk}_1 \\mathrm{v}_1+\\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_1+\\mathrm{k}_0} & \\mathrm{r}_1\\left(\\mathrm{uk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_2 & \\mathrm{r}_2 \\frac{\\mathrm{uk}_2 \\mathrm{v}_2+\\mathrm{k}_1 \\mathrm{v}_1+\\mathrm{wk}_0 \\mathrm{v}_0}{\\mathrm{uk}_2+\\mathrm{k}_1+\\mathrm{wk}_0} & \\mathrm{r}_2\\left(\\mathrm{uk}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{k}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{wk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_3 & \\mathrm{r}_3 \\frac{\\mathrm{uk}_3 \\mathrm{v}_3+\\mathrm{k}_2 \\mathrm{v}_2+\\mathrm{wk}_1 \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_3+\\mathrm{k}_2+\\mathrm{wk}_1+\\mathrm{w}^2 \\mathrm{k}_0} & \\mathrm{r}_3\\left(\\mathrm{uk}_3^{\\dagger} \\mathrm{v}_3+\\mathrm{k}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{wk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline\n\\end{array}`$\n\n$`\\left[\\begin{array}{ll}\n\\mathrm{y}_{20} & \\cdots \\mathrm{y}_{2 \\mathrm{c}}\n\\end{array}\\right]=\\left[\\begin{array}{lll}\n\\mathrm{r}_{20} & \\cdots & \\mathrm{r}_{2 \\mathrm{c}}\n\\end{array}\\right]`$\n$`\\left(\\left[\\begin{array}{ccc}\n\\mathrm{u}_{00} & \\cdots & \\mathrm{u}_{0 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{u}_{\\mathrm{c} 0} & \\cdots & \\mathrm{u}_{\\mathrm{cc}}\n\\end{array}\\right]\\left[\\begin{array}{ccc}\n\\mathrm{k}_{20} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{20} \\mathrm{v}_{2 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{2 \\mathrm{c}}\n\\end{array}\\right]+\\left[\\begin{array}{ccc}\n\\mathrm{k}_{10} \\mathrm{v}_{10} & \\cdots & \\mathrm{k}_{10} \\mathrm{v}_{1 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{1 \\mathrm{c}} \\mathrm{v}_{10} & \\cdots & \\mathrmk_{1 \\mathrm{c}} \\mathrm{v}_{1 \\mathrm{c}}\n\\end{array}\\right]+\\left[\\begin{array}{ccc}\n\\mathrm{w}_{00} & \\cdots & \\mathrm{w}_{0 \\mathrm{c}} \\\\\n\\vdots & \\dders & \\vdols \\\\\n\\mathrm{w}_{\\mathrm{c} 0} & \\cds & the w ccc\n\\end{array}\\right]\\left[\\begin{array}{ccc}\n\\mathrm{k}_{00} \\mathrm{v}_{00} & \\cds & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v00,\n\\vdols & dders & the k00 v0......### 训练\u002F微调\n\npip install deepspeed==0.7.0 \u002F\u002F pip install pytorch-lightning==1.9.5 \u002F\u002F torch 1.13.1+cu117\n\n注意：在少量数据上训练时，建议加入权重衰减（0.1 或 0.01）和 Dropout（0.1 或 0.01）。可以尝试以下组合：x=x+dropout(att(x))、x=x+dropout(ffn(x))、x=dropout(x+att(x))、x=dropout(x+ffn(x)) 等。\n\n**从零开始训练 RWKV-4：** 运行 train.py，默认使用 enwik8 数据集（解压 https:\u002F\u002Fdata.deepai.org\u002Fenwik8.zip）。\n\n你将训练的是“GPT”版本，因为它可以并行化且训练速度更快。RWKV-4 具有外推能力，因此使用 ctxLen 1024 训练的模型也可以很好地处理 ctxLen 为 2500+ 的情况。你可以用更长的 ctxLen 对模型进行微调，它会迅速适应更长的上下文长度。\n\n**微调 RWKV-4 Pile 模型：** 使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-v2-RNN-Pile\u002Ftree\u002Fmain\u002FRWKV-v3 中的 ‘prepare-data.py’ 将 .txt 文件分词并转换为 train.npy 数据。然后使用 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v4neo\u002Ftrain.py 来训练该模型。\n\n阅读 src\u002Fmodel.py 中的推理代码，并尝试将最终隐藏状态（.xx、.aa、.bb）作为其他任务的忠实句子嵌入。建议从 .xx 和 .aa\u002F.bb 开始（即 .aa 除以 .bb）。\n\n用于微调 RWKV-4 Pile 模型的 Colab 笔记本：https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fresloved\u002FRWKV-notebooks\u002Fblob\u002Fmaster\u002FRWKV_v4_RNN_Pile_Fine_Tuning.ipynb\n\n**大型语料库：** 使用 https:\u002F\u002Fgithub.com\u002FAbel2076\u002Fjson2binidx_tool 将 .jsonl 文件转换为 .bin 和 .idx 格式。\n\n.jsonl 格式的示例（每行为一个文档）：\n```\n{\"text\": \"这是第一篇文档。\"}\n{\"text\": \"你好\\n世界\"}\n{\"text\": \"1+1=2\\n1+2=3\\n2+2=4\"}\n```\n生成代码如下：\n```\nss = json.dumps({\"text\": text}, ensure_ascii=False)\nout.write(ss + \"\\n\")\n```\n\n**无限上下文长度训练（开发中）：** https:\u002F\u002Fgithub.com\u002FBlealtan\u002FRWKV-LM-LoRA\u002Ftree\u002Fdev-infctx\n\n### 如何将 RWKV 隐藏状态用作文本嵌入\n\n以 RWKV 14B 为例，其状态包含 200 个向量，即每个块有 5 个向量：fp16 (.xx)、fp32 (.aa)、fp32 (.bb)、fp32 (.pp)、fp16 (.xx)。\n\n不要进行平均池化，因为状态中的不同向量（.xx、.aa、.bb、.pp、.xx）具有非常不同的含义和范围。你可能需要移除 .pp。\n\n我建议首先收集每个向量各通道的均值和标准差统计信息，并对所有向量进行归一化处理（注意：归一化应与具体数据无关，需基于多种文本数据进行统计）。然后训练一个线性分类器。\n\n## 向 RWKV-5 发展（仅记录一些新想法）\n\n### 最新设计\n\nRWKV-5 采用多头机制，此处展示的是其中的一个头。每个头还配备了一个 LayerNorm（实际上是 GroupNorm）。\n\n$`\n\\begin{array}{|l|l|l|}\n\\hline & \\text { RWKV-4，使用实数值 } k \\,\\&\\, v \\,\\&\\, u \\,\\&\\, w & \\text { RWKV-5，使用矩阵值 } \\mathrm{k}^{\\dagger} \\mathrm{v} \\,\\&\\, \\mathrm{u} \\,\\&\\, \\mathrm{w} \\\\\n\\hline \\mathrm{y}_0 & \\mathrm{r}_0 \\frac{\\mathrm{uk}_0 \\mathrm{v}_0}{\\mathrm{uk}_0} & \\mathrm{r}_0\\left(\\mathrm{uk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_1 & \\mathrm{r}_1 \\frac{\\mathrm{uk}_1 \\mathrm{v}_1+\\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_1+\\mathrm{k}_0} & \\mathrm{r}_1\\left(\\mathrm{uk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_2 & \\mathrm{r}_2 \\frac{\\mathrm{uk}_2 \\mathrm{v}_2+\\mathrm{k}_1 \\mathrm{v}_1+\\mathrm{wk}_0 \\mathrm{v}_0}{\\mathrm{uk}_2+\\mathrm{k}_1+\\mathrm{wk}_0} & \\mathrm{r}_2\\left(\\mathrm{uk}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{k}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{wk}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline \\mathrm{y}_3 & \\mathrm{r}_3 \\frac{\\mathrm{uk}_3 \\mathrm{v}_3+\\mathrm{k}_2 \\mathrm{v}_2+\\mathrm{wk}_1 \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0 \\mathrm{v}_0}{\\mathrm{uk}_3+\\mathrm{k}_2+\\mathrm{wk}_1+\\mathrm{w}^2 \\mathrm{k}_0} & \\mathrm{r}_3\\left(\\mathrm{uk}_3^{\\dagger} \\mathrm{v}_3+\\mathrm{k}_2^{\\dagger} \\mathrm{v}_2+\\mathrm{wk}_1^{\\dagger} \\mathrm{v}_1+\\mathrm{w}^2 \\mathrm{k}_0^{\\dagger} \\mathrm{v}_0\\right) \\\\\n\\hline\n\\end{array}`$\n\n$`\\left[\\begin{array}{ll}\n\\mathrm{y}_{20} & \\cdots \\mathrm{y}_{2 \\mathrm{c}}\n\\end{array}\\right]=\\left[\\begin{array}{lll}\n\\mathrm{r}_{20} & \\cdots & \\mathrm{r}_{2 \\mathrm{c}}\n\\end{array}\\right]`$\n$`\\left(\\left[\\begin{array}{ccc}\n\\mathrm{u}_{00} & \\cdots & \\mathrm{u}_{0 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{u}_{\\mathrm{c} 0} & \\cdots & \\mathrm{u}_{\\mathrm{cc}}\n\\end{array}\\right]\\left[\\begin{array}{ccc}\n\\mathrm{k}_{20} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{20} \\mathrm{v}_{2 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdots \\\\\n\\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{20} & \\cdots & \\mathrm{k}_{2 \\mathrm{c}} \\mathrm{v}_{2 \\mathrm{c}}\n\\end{array}\\right]+\\left[\\begin{array}{ccc}\n\\mathrm{k}_{10} \\mathrm{v}_{10} & \\cdots & \\mathrm{k}_{10} \\mathrm{v}_{1 \\mathrm{c}} \\\\\n\\vdots & \\ddots & \\vdotedit\n```\n\n### 一些旧想法\n\n1. 目前的时间衰减是 0.999^T（0.999 可学习）。可以将其改为类似 (0.999^T + 0.1) 的形式，其中 0.1 也是可学习的。这样 0.1 部分将永远保留下来。或者，使用 A^T + B^T + C 的形式，分别代表快速衰减、慢速衰减和常数项。甚至可以采用不同的衰减公式，比如用 K^2 替代 e^K 作为衰减成分，或者不进行归一化。\n\n2. 在某些通道中使用复数值衰减（即旋转而非单纯的衰减）。\n\n3. 是否可以注入一些可训练且可外推的位置编码？\n\n4. 除了二维旋转之外，还可以尝试其他李群，例如三维旋转（SO(3)）。非交换的 RWKV 哈哈。\n\n5. RWKV 在模拟设备上可能会非常出色（可搜索“模拟矩阵-向量乘法”和“光子矩阵-向量乘法”）。RNN 模式对硬件非常友好（存内计算）。它也可以作为脉冲神经网络（SNN）实现（https:\u002F\u002Fgithub.com\u002Fridgerchu\u002FSpikeGPT）。我想知道它是否能被优化以用于量子计算。\n\n6. 可训练的初始隐藏状态（xx aa bb pp xx）。\n\n7. 使用逐层（甚至逐行\u002F逐列、逐元素）的学习率，并测试 Lion 优化器。\n\n### 视觉任务\n\n1. 我发现添加二维位置编码效果不错：\n```\nself.pos_emb_x = nn.Parameter(torch.zeros((1,args.my_pos_emb,args.n_embd)))\nself.pos_emb_y = nn.Parameter(torch.zeros((args.my_pos_emb,1,args.n_embd)))\n...\nx = x + pos_emb_x + pos_emb_y\n```\n\n2. 在基于 BPE 的语言模型中，最好使用 [偏移 1 个 token] 的方式（在字符级英语模型中可以混合更多 token）。然而，如果图像大小为 N×N，也可以尝试 [偏移 N 个（或 N-1 个、N+1 个）token]，因为这相当于将 [当前位置上方的 token（或待预测位置上方的 token）] 与 [当前 token] 混合。可以在 “ATT” 和 “FFN” 中尝试不同的偏移风格，或者混合多种偏移方式——例如将 [token A] 与 [token A-1] 和 [token A-(N-1)] 等混合起来。\n\n### 杂项\n\n也许我们可以通过简单地重复上下文来提升记忆能力（我猜重复两次就足够了）。示例：参考 -> 参考（再次）-> 问题 -> 答案\n\n#### 想法：字节感知嵌入\n\n这个想法是让词汇表中的每个 token 都了解自身的长度及其原始 UTF-8 字节表示。\n\n设 a = 词汇表中所有 token 的最大长度。定义 AA : float[a][d_emb]\n\n设 b = 词汇表中所有 token 的最大 UTF-8 字节长度。定义 BB : float[b][256][d_emb]\n\n对于词汇表中的每个 token X，设 [x0, x1, ..., xn] 为其原始 UTF-8 字节。我们将为其嵌入 EMB(X) 添加一些额外的值：\n\nEMB(X) += AA[len(X)] + BB[0][x0] + BB[1][x1] + ... + BB[n][xn]（注：AA 和 BB 是可学习的权重）\n\n* 我们也可以对最终的 Linear(d_emb, n_vocab) 投影层这样做。\n* 可以使用一些小型网络来生成 AA 和 BB，以增加正则化效果（例如，BB[m][xi] 和 BB[n][xi] 应该具有一定的关联性）。\n\n#### 旧想法\n\n我有一个改进分词的想法。我们可以硬编码一些通道来赋予其特定含义。例如：\n\n通道 0 = “空格”\n\n通道 1 = “首字母大写”\n\n通道 2 = “全部字母大写”\n\n因此：\n\n“abc”的嵌入：[0, 0, 0, x0, x1, x2, ..]\n\n“ abc”的嵌入：[1, 0, 0, x0, x1, x2, ..]\n\n“ Abc”的嵌入：[1, 1, 0, x0, x1, x2, ..]\n\n“ABC”的嵌入：[0, 0, 1, x0, x1, x2, ...]\n\n......\n\n这样它们就可以共享大部分嵌入。并且我们可以快速计算出 “abc” 所有变体的输出概率。\n\n注意：上述方法假设 p(\" xyz\") \u002F p(\"xyz\") 对任何 \"xyz\" 都相同，但这可能是错误的。\n\n更好的做法是：将 emb_space、emb_capitalize_first、emb_capitalize_all 定义为 emb 的函数。\n\n也许最好的办法是让 ‘abc’、‘ abc’ 等共享其嵌入的最后 90%。\n\n目前，我们的所有分词器都花费了大量的条目来表示 ‘abc’、‘ abc’、‘ Abc’ 等的所有变体。此外，如果这些变体在数据集中很少出现，模型也无法发现它们实际上是相似的。这里的方法可以改善这一点。我计划在 RWKV 的新版本中进行测试。\n\n#### 想法：更好的初始状态\n\n单轮问答示例：\n\n1. 生成所有维基文档的最终状态。\n\n2. 对于任何用户的问题，找到最佳的维基文档，并将其最终状态作为初始状态。\n\n3. 训练一个模型，直接为任何用户的问题生成最优的初始状态。\n\n不过，对于多轮问答来说，这可能会稍微复杂一些 :)\n\n## 工作原理\n\nRWKV 受苹果公司 AFT（https:\u002F\u002Farxiv.org\u002Fabs\u002F2105.14103）的启发。\n\n此外，它还使用了我提出的多项技巧，例如：\n\n* SmallInitEmb：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FSmallInitEmb（适用于所有 Transformer），有助于提高嵌入质量，并稳定 Post-LN（这是我正在使用的）。\n\n* Token-shift：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM#token-shift-time-shift-mixing（适用于所有 Transformer），尤其对字符级模型很有帮助。\n\n* Head-QK：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM#the-head-qk-trick-learning-to-copy-and-avoid-tokens（适用于所有 Transformer）。注意：虽然有用，但我为了保持 Pile 模型 100% RNN 特性，已将其禁用。\n\n* FFN 中的额外 R-gate（适用于所有 Transformer）。我还使用了 Primer 中的 reluSquared。\n\n* 更好的初始化：我将大多数矩阵初始化为 ZERO（参见 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fblob\u002Fmain\u002FRWKV-v2-RNN\u002Fsrc\u002Fmodel.py 中的 RWKV_Init）。\n\n* 可以将参数从小模型迁移到大模型中（注意：我还会对其进行排序和平滑处理），以加快并提高收敛速度（参见 https:\u002F\u002Fwww.reddit.com\u002Fr\u002FMachineLearning\u002Fcomments\u002Fumq908\u002Fr_rwkvv2rnn_a_parallelizable_rnn_with\u002F）。\n\n* 我的 CUDA 内核：https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-CUDA，用于加速训练。\n\n## 伪代码（从上到下执行）：\n\n![RWKV-v2-RNN](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_02009191186b.png)\n\na、b、c、d 四个因子共同作用，构建时间衰减曲线：[X, 1, W, W^2, W^3, ...]。\n\n写出 “位置 2 的 token” 和 “位置 3 的 token” 的公式，你就能明白其中的原理：\n* a 和 b：分别是 kv 和 k 的指数移动平均值。\n* c 和 d：是 a 和 b 与自注意力机制结合后的结果。\n\nkv \u002F k 是记忆机制。如果通道中的 W 接近 1，那么 k 值较高的 token 就可以被长期记住。\n\nR-gate 对性能至关重要。k 表示该 token 的信息强度（传递给后续 token），而 r 则决定是否将该信息应用到当前 token 上。\n\n## RWKV-3 的改进\n\n在 SA 和 FF 层中，分别为 R \u002F K \u002F V 使用不同的可训练 TimeMix 因子。示例：\n```python\nxx = self.time_shift(x)\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxv = x * self.time_mix_v + xx * (1 - self.time_mix_v)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n```\n\n使用 preLN 而不是 postLN（更稳定且收敛更快）：\n```python\nif self.layer_id == 0:\n\tx = self.ln0(x)\nx = x + self.att(self.ln1(x))\nx = x + self.ffn(self.ln2(x))\n```\n\n## 解释 RWKV-3 GPT 模式的代码\n\n### GPT 模式 - 概述\n\nRWKV-3 GPT 模式的构建模块与普通的 preLN GPT 类似。\n\n唯一的区别是在嵌入之后多了一个 Layer Normalization 层。请注意，在训练完成后，可以将这个 Layer Normalization 层合并到嵌入层中。\n```python\nx = self.emb(idx)  # 输入：idx = token 索引\nx = self.ln_emb(x) # 嵌入后的额外 Layer Normalization\nx = x + self.att_0(self.ln_att_0(x)) # preLN\nx = x + self.ffn_0(self.ln_ffn_0(x))\n...\nx = x + self.att_n(self.ln_att_n(x))\nx = x + self.ffn_n(self.ln_ffn_n(x))\nx = self.ln_head(x) # 投影前的最终 Layer Normalization\nx = self.head(x)    # 输出：x = logits\n```\n重要的是要将嵌入层初始化为非常小的值，例如 `nn.init.uniform_(a=-1e-4, b=1e-4)`，以便利用我的技巧 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FSmallInitEmb。\n\n对于 15 亿参数的 RWKV-3 模型，我使用 Adam 优化器（无权重衰减，无 dropout）在 8 张 A100 40G 显卡上进行训练。\n\nbatchSz = 32 * 896，ctxLen = 896。由于我使用的是 tf32 精度，因此 batchSz 稍微偏小。\n\n在前 150 亿个 token 的训练中，学习率固定为 3e-4，动量参数 beta=(0.9, 0.99)。\n\n随后我将 beta 调整为 (0.9, 0.999)，并采用指数衰减的学习率策略，最终在训练到 3320 亿个 token 时将学习率降至 1e-5。\n\n### GPT 模式 - ATT 块\n\nRWKV-3 并没有传统意义上的注意力机制，但我们仍然称这一模块为 ATT。\n```python\nB, T, C = x.size() # x = (Batch,Time,Channel)\n\n# 将当前时间步的 x 与前一个时间步的 x 混合，生成 xk、xv 和 xr\nxx = self.time_shift(x) # self.time_shift = nn.ZeroPad2d((0,0,1,-1))\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxv = x * self.time_mix_v + xx * (1 - self.time_mix_v)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n\n# 使用 xk、xv 和 xr 生成 k、v 和 r\nk = self.key(xk).transpose(-1, -2)\nv = self.value(xv).transpose(-1, -2)\nr = self.receptance(xr)\nk = torch.clamp(k, max=60) # 限制 k 的值以防止溢出\nk = torch.exp(k)\nkv = k * v\n\n# 计算 W 曲线 = [e^(-n * e^time_decay), e^(-(n-1) * e^time_decay), ..., 1, e^(time_first)]\nself.time_w = torch.cat([torch.exp(self.time_decay) * self.time_curve.to(x.device), self.time_first], dim=-1)\nw = torch.exp(self.time_w)\n\n# 使用 W 分别混合 kv 和 k。为避免除零错误，在 wk 中加入 K_EPS\nif RUN_DEVICE == 'cuda':\n    wkv = TimeX.apply(w, kv, B,C,T, 0)\n    wk = TimeX.apply(w, k, B,C,T, K_EPS)\nelse:\n    w = w[:,-T:].unsqueeze(1)\n    wkv = F.conv1d(nn.ZeroPad2d((T-1, 0, 0, 0))(kv), w, groups=C)\n    wk = F.conv1d(nn.ZeroPad2d((T-1, 0, 0, 0))(k), w, groups=C) + K_EPS\n\n# RWKV 公式\nrwkv = torch.sigmoid(r) * (wkv \u002F wk).transpose(-1, -2)\nrwkv = self.output(rwkv) # 最终输出投影\n```\n\nself.key、self.receptance 和 self.output 矩阵均初始化为零。\n\ntime_mix、time_decay 和 time_first 向量则从一个较小的已训练模型中迁移而来（注意：我还对这些向量进行了排序和平滑处理）。\n\n### GPT 模式 - FFN 块\n\nFFN 块相比普通 GPT 有三个创新点：\n\n1. 我的时间混合技巧。\n\n2. 来自 Primer 论文的 sqReLU。\n\n3. 额外的受容门（类似于 ATT 块中的受容门）。\n```python\n# 将当前时间步的 x 与前一个时间步的 x 混合，生成 xk 和 xr\nxx = self.time_shift(x)\nxk = x * self.time_mix_k + xx * (1 - self.time_mix_k)\nxr = x * self.time_mix_r + xx * (1 - self.time_mix_r)\n\n# 普通的 FFN 操作\nk = self.key(xk)\nk = torch.square(torch.relu(k)) # 来自 Primer 论文\nkv = self.value(k)\n\n# 对 kv 应用额外的受容门\nrkv = torch.sigmoid(self.receptance(xr)) * kv\nreturn rkv\n```\n\nself.value 和 self.receptance 矩阵均初始化为零。\n\n## RWKV-4 改进\n\n![RWKV-v3-plan](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_5de7ddc9a3e1.png)\n\n## 从GPT到RWKV（公式）\n\n设F[t]为时刻t时的系统状态。\n\n设x[t]为时刻t时的新外部输入。\n\n在GPT中，预测F[t+1]需要考虑F[0], F[1], .. F[t]。因此，生成长度为T的序列需要O(T^2)的时间复杂度。\n\nGPT的**简化公式**如下：\n\n![F[\\mathrm{t}+1]=\\frac{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}]) \\cdot(\\mathbf{V}F[\\mathrm{i}])}{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B%5Cmathrm%7Bt%7D%2B1%5D%3D%5Cfrac%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D)\n\n理论上它非常强大，然而这并不意味着我们能够用常规优化器充分发挥其能力。我怀疑当前的方法难以应对如此复杂的损失景观。\n\n相比之下，RWKV的**简化公式**（并行模式，与苹果的AFT类似）如下：\n\n![F[\\mathrm{t}+1]=\\sigma(\\mathbf{R}x[\\mathrm{t}]) \\cdot \\frac{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K}F[\\mathrm{i}]) \\cdot(\\mathbf{V}F[\\mathrm{i}])}{\\sum_{\\mathrm{i}=0}^{\\mathrm{t}} \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K }F[\\mathrm{i}])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B%5Cmathrm%7Bt%7D%2B1%5D%3D%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot+%5Cfrac%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D%7B%5Csum_%7B%5Cmathrm%7Bi%7D%3D0%7D%5E%7B%5Cmathrm%7Bt%7D%7D+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B%5Cmathrm%7Bi%7D%5D%29%7D)\n\n其中，R、K、V是可训练的矩阵，而W是一个可训练的向量（用于每个通道的时间衰减因子）。\n\n在GPT中，F[i]对F[t+1]的贡献由![ \\exp (\\mathbf{Q}x[\\mathrm{t}] * \\mathbf{K}F[\\mathrm{i}]) ](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle++%5Cexp+%28%5Cmathbf%7BQ%7Dx%5B%5Cmathrm%7Bt%7D%5D+%2A+%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+) 权重决定。\n\n而在RWKV-2中，F[i]对F[t+1]的贡献则由 ![\\sigma(\\mathbf{R}x[\\mathrm{t}]) \\cdot \\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i})) \\cdot \\exp (\\mathbf{K}F[\\mathrm{i}]) ](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bi%7D%5D%29+) 权重决定。\n\n* 其中的 ![\\sigma](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma) 是一个非线性激活函数，我们可以使用Sigmoid。\n* 注意 ![\\sigma(\\mathbf{R}x[\\mathrm{t}])](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Csigma%28%5Cmathbf%7BR%7Dx%5B%5Cmathrm%7Bt%7D%5D%29) 并不在分母中，我称R为“接受度”。\n* 而 ![\\exp (\\mathbf{W} \\cdot(\\mathrm{t}-\\mathrm{i}))](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+%5Cexp+%28%5Cmathbf%7BW%7D+%5Ccdot%28%5Cmathrm%7Bt%7D-%5Cmathrm%7Bi%7D%29%29) 则是时间衰减因子。我在2020年8月就提出了同样的想法（按距离缩放注意力），并称之为“时间加权”（请查看 https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FminGPT-tuned 的提交历史）。\n\n关键在于：我们可以将其改写成一个RNN（递归公式）。注意：\n\n![F[1]=\\sigma(\\mathbf{R }x[0]) \\cdot \\frac{ \\exp (\\mathbf{K }F[0]) \\cdot(\\mathbf{V }F[0])}{\\exp (\\mathbf{K }F[0])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B1%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5B0%5D%29+%5Ccdot+%5Cfrac%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B0%5D%29%7D%7B%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29%7D)\n\n![F[2]=\\sigma(\\mathbf{R }x[1]) \\cdot \\frac{ \\exp (\\mathbf{K }F[1]) \\cdot(\\mathbf{V }F[1])+\\exp (\\mathbf{W} ) \\cdot \\exp (\\mathbf{K }F[0]) \\cdot(\\mathbf{V }F[0])}{ \\exp (\\mathbf{K }F[1])+\\exp (\\mathbf{W} ) \\cdot exp (mathbf{K }F[0])}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5B2%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5B1%5D%29+%5Ccdot+%5Cfrac%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B1%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B1%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B0%5D%29%7D%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B1%5D%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29%7D)\n\n因此，很容易验证以下关系：\n\n![F[t+1]=\\sigma(\\mathbf{R }x[t]) \\cdot \\frac{\\exp (\\mathbf{K}F[\\mathrm{t}]) \\cdot(\\mathbf{V}F[\\mathrm{t}])+\\exp (\\mathbf{W}) \\cdot A[\\mathrm{t}]}{ \\exp (\\mathbf{K}F[\\mathrm{t}])+\\exp (\\mathbf{W}) \\cdot B[\\mathrm{t}]}](https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Ccolor%7Bblack%7D%5Cdisplaystyle+F%5Bt%2B1%5D%3D%5Csigma%28%5Cmathbf%7BR+%7Dx%5Bt%5D%29+%5Ccdot+%5Cfrac%7B%5Cexp+%28%5Cmathbf%7BK%7DF%5B%5Cmathrm%7Bt%7D%5D%29+%5Ccdot%28%5Cmathbf%7BV%7DF%5B%5Cmathrm%7Bt%7D%29%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+A%5B%5Cmathrm%7Bt%7D%5D%7D%7B+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B%5Cmathrm%7Bt%7D%29%29%2B%5Cexp+%28%5Cmathbf%7BW%7D+%29+%5Ccdot+%5Cexp+%28%5Cmathbf%7BK+%7DF%5B0%5D%29+%5Ccdot%28%5Cmathbf%7BV+%7DF%5B0%5D%29%7D)\n\n其中，A[t]和B[t]分别是上一步的分子和分母。\n\n我认为RWKV之所以性能优异，是因为W的作用类似于反复应用一个对角矩阵。注意(P^{-1} D P)^n = P^{-1} D^n P，因此它等同于反复应用一个可对角化的矩阵。\n\n此外，它还可以被转化为连续的常微分方程（有点类似于状态空间模型）。这一点我将在后续文章中详细说明。\n\n## 星标历史\n\n[![星标历史图](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_8b30a909dab8.png)](https:\u002F\u002Fstar-history.com\u002F#BlinkDL\u002FRWKV-LM&Date)\n\n## 多模态想法\n\n我有一个关于[文本 --> 32x32 RGB图像]的想法，使用语言模型（Transformer、RWKV等）来实现。我很快就会进行测试。\n\n首先，使用语言模型的损失函数（而不是L2损失），这样生成的图像就不会模糊。\n\n其次，进行颜色量化。例如，只允许R\u002FG\u002FB每个通道有8个等级。这样一来，图像的词汇表大小就是8×8×8=512（针对每个像素），而不是2^24。因此，一张32x32的RGB图像就可以表示为一个长度为1024、词汇表大小为512的序列（图像标记），这正是普通语言模型的典型输入格式。\n（之后我们可以使用扩散模型来上采样并生成RGB888图像。也许我们也可以用语言模型来做这件事。）\n\n第三，使用易于模型理解的二维位置嵌入。\n例如，在前64个（=32+32）通道中加入独热编码的X和Y坐标。假设某个像素位于x=8，y=20，那么就在第8个通道和第52个通道（=32+20）中分别加1。\n此外，我们还可以将归一化到0~1范围的浮点X和Y坐标添加到另外两个通道中。其他周期性的位置编码也可能有所帮助（我会进一步测试）。\n\n最后，在DataLoader中进行颜色量化时使用随机四舍五入。\n例如，如果某个像素的浮点值是4.578，那么就有57.8%的概率取5，而42.2%的概率取4。\n在预测时，我们可以同时考虑4和5这两种可能性，但如果预测结果是4，损失会更高。\n\n多任务训练也可能有所帮助。我将尝试以下数据格式：\n[TxtFirst] [图像描述（文本标记）] [图像] [图像标记]\n以及有时\n[ImgFirst] [图像标记] [文本] [图像描述（文本标记）]\n……在DataLoader中应随机打乱图像的顺序，而[TxtFirst]、[ImgFirst]、[Img]、[Txt]则是特殊标记。\n同时对整个数据集进行随机采样。这样，有时模型会先看到图像标记，再看到对应的文本标记，这就构成了一个[图像 -> 文本]的任务。此外，模型还会看到一些部分的图像和部分的文本。我认为，基于字符级别的语言模型可能会帮助模型在图像上生成正确的文字。\n\n## 如何从大型数据集中采样（用于训练）\n\n我使用一个小技巧来以确定性但又足够随机的方式从Pile数据集中采样。\n\n假设Pile数据集有x个块（一个块等于ctx_len个标记）。\n\n选择一个比x略小的素数p，并确保p ≡ 2 (mod 3)。\n\n使用(step * step * step) mod p来进行采样。为了增加随机性，可以在step中加入一些偏置。\n\n## top-p-x采样方法（用于推理）\n\n我们提出了一种新的采样方法，称为top-p-x：\n\n它类似于top-p，唯一的区别在于你还会保留所有概率大于x的标记。\n可以先尝试x=0.01。\n\n## 基于变分法的损失曲线优化学习率调度方案\n\n我提出了一种简单的新方法来寻找更好的学习率调度方案。这种方法成本效益高，且适用于大型语言模型。其核心思想是，我们可以对损失曲线随学习率变化的动力学（现象学）进行建模，并利用变分法直接计算出一个优美的闭式解学习率曲线。此外，我们还可以相当准确地预测最终的损失。\n\n更新：在“结论1”中，使用最佳拟合区间（忽略初始阶段我们的近似失效的部分）来拟合参数。\n尝试如下方案：固定学习率为1小时，然后在12小时内指数衰减至0.2倍的学习率，并选择t=[1小时, 13小时]这段区间。\n在最后三张图中，黑色代表新学习率调度方案的预测损失曲线，蓝色代表原始（未优化）的实际损失曲线，橙色代表新的学习率调度方案。\n![better_lr_schedule](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_4ec9545eecee.png)\n\n# RWKV v1\n\n我们提出了RWKV语言模型，该模型交替使用时间混合层和通道混合层：\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+%5Cbegin%7Balign%2A%7D%0A%5Ctext%7BTime-mix+%3A%7D+%26%26+%5Ctext%7BTM%7D_%7Bt%2Cc%7D+%26%26%3D%26%26%5Ctext%7Bsigin%7D%28%5Ctext%7BR%7D_%7Bt%2Cc%7D%29+%26%26%5Ccdot%26%26+%26%26%5Ctextstyle%5Csum_%7Bu%7D+%26%26%5Ctextbf%7BW%7D_%7Bt%2Cu%2Cc%7D+%26%26%5Ccdot%26%26+%5Ctext%7Bsoftmax%7D_t%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29+%26%26%5Ccdot%26%26+%5Ctext%7BV%7D_%7Bu%2Cc%7D%5C%5C%0A%5Ctext%7BChannel-mix+%3A%7D+%26%26+%5Ctext%7BCM%7D_%7Bt%2Cc%7D+%26%26%3D%26%26%5Ctext%7Bsigin%7D%28%5Ctext%7BR%7D_%7Bt%2Cc%7D%29+%26%26%5Ccdot%26%26+%26%26%5Ctextstyle%5Csum_d+%26%26%5Ctextbf%7BW%7D_%7Bc%2Cd%7D+%26%26%5Ccdot%26%26+%5Ctext%7Bgelu%7D%28%5Ctext%7BK%7D_%7Bt%2Fd%7D%29+%26%26%5Ccdot%26%26+%5Ctext%7BV%7D_%7Bt%2Fd%7D%0A%5Cend%7Balign%2A%7D%0A\" \nalt=\"\\begin{align*}\n\\text{Time-mix :} && \\text{TM}_{t,c} &&=&&\\text{sigmoid}(\\text{R}_{t,c}) &&\\cdot&& &&\\textstyle\\sum_{u} &&\\textbf{W}_{t,u,c} &&\\cdot&& \\text{softmax}_t(\\text{K}_{u,c}) &&\\cdot&& \\text{V}_{u,c}\\\\\n\\text{Channel-mix :} && \\text{CM}_{t,c} &&=&&\\text{sigmoid}(\\text{R}_{t,c}) &&\\cdot&& &&\\textstyle\\sum_d &&\\textbf{W}_{c,d} &&\\cdot&& \\text{gelu}(\\text{K}_{t,d}) &&\\cdot&& \\text{V}_{t,d}\n\\end{align*}\n\">\n\n* R、K、V是由输入经过线性变换生成的，而W则是可学习的参数。RWKV的核心思想是将注意力分解为R（目标）* W（源与目标）* K（源）。因此，我们可以将R称为“接受度”，而sigmoid函数则表明它的取值范围在0到1之间。\n\n* 时间混合层类似于AFT（https:\u002F\u002Farxiv.org\u002Fabs\u002F2105.14103）。两者有两个不同之处。\n\n(1) 我们改变了归一化方式（分母）。对于掩码语言模型，我们定义：\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+%5Ctext%7Bsoftmax%7D_t%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29+%3D+%5Cfrac%7B%5Cexp%28%5Ctext%7BK%7D_%7Bu%2Cc%7D%29%7D%7B%5Csum_%7Bv+%5Cleq+t%7D%5Cexp%28%5Ctext%7BK%7D_%7Bv%2Cc%7D%29%7D\" \nalt=\"\\text{softmax}_t(\\text{K}_{u,c}) = \\frac{\\exp(\\text{K}_{u,c})}{\\sum_{v \\leq t}\\exp(\\text{K}_{v,c})}\">\n\n**(更新：我们在v2版本中使用了原始的AFT归一化方式）**\n \n为了快速且稳定的收敛，我们将K和R矩阵（以及输出投影矩阵）初始化为零。\n \n(2) 我们将W_{t,u,c}分解，并引入多头W（这里h是c对应的头）：\n\n\u003Cimg src=\n\"https:\u002F\u002Frender.githubusercontent.com\u002Frender\u002Fmath?math=%5Cdisplaystyle+W_%7Bt%2Cu%2Cc%7D%3Df_h%28t-u%29%5Ccdot+%5Calpha_h%28u%29+%5Ccdot+%5Cbeta_h%28t%29\" \nalt=\"W_{t,u,c}=f_h(t-u)\\cdot \\alpha_h(u) \\cdot \\beta_h(t)\">\n\n此外，我们还在时间混合层的最终输出上乘以γ(t)。引入α、β、γ这些因子的原因是，当t较小时，上下文的规模较小，可以通过这些因子来弥补。\n\n**(更新：我们在v2-RNN版本中去除了α、β、γ因子，将W限制为一种简单的形式，从而可以将其重写为RNN）**\n\n* 通道混合层类似于GeGLU（https:\u002F\u002Farxiv.org\u002Fabs\u002F2002.05202），只是额外增加了一个R因子。为了快速且稳定的收敛，我们将R和W矩阵初始化为零。\n\n* 最后，我们还加入了额外的标记移位（时间移位混合），就像（https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FminGPT-tuned）中那样。\n\n# 令牌移位（时间移位混合）\n\n令牌移位显式地使用（该令牌的一半通道）与（前一个令牌的一半通道），来生成所有的向量（QKV、RWKV 等）。\n\n```\nself.time_shift = nn.ZeroPad2d((0,0,1,-1))\n\nx = torch.cat([self.time_shift(x[:, :, :C\u002F\u002F2]), x[:, :, C\u002F\u002F2:]], dim = -1)\n```\n\n将通道数减半并进行一次移位，在字符级别的英语和中文语言模型中效果非常好。\n\n然而，对于 BPE 级别的英语语言模型，只有当你的嵌入维度足够大时（至少 1024 维——因此常见的小型 L12-D768 模型并不够用）才会有效。\n\n我对令牌移位有效性的理解如下：\n\n当我们训练 GPT 时，一个标记的隐藏表示需要完成两个不同的任务：\n\n1. 预测下一个标记。有时这很容易（下一个标记很明显）。\n2. 收集所有之前的上下文信息，以便后续标记可以利用这些信息。这一点总是很困难。\n\n移位后的通道可以专注于第 2 个任务，从而实现良好的信息传播。这就像是某种残差连接，或者是在 Transformer 内部加入了一个小型 RNN。\n\n你也可以在普通的 QKV 自注意力机制中使用令牌移位。我查看了权重，发现 V 很喜欢移位后的通道，而 Q 则不太依赖。仔细想想也确实有道理。此外，我还发现高层层中可能需要减少混合的程度。\n\n附注：这个仓库中有一个名为 MHA_pro 的模型，性能非常出色。不妨试一试 :)\n\n# Head-QK 技巧：学习复制和避免特定标记\n\n在普通的 Transformer 中，小型模型很难复制上下文中出现的特定标记（如人名）。我们通过在最终输出中添加额外的 Q 和 K，使模型可以直接复制（或避免）上下文中的特定标记。之后，如果你观察学习到的权重，会发现模型实际上已经学会了命名实体识别（NER）。\n```\nq = self.head_q(x)[:,:T,:] # 投影到 256 维\nk = self.head_k(x)[:,:T,:] # 投影到 256 维\nc = (q @ k.transpose(-2, -1)) * (1.0 \u002F 256)\nc = c.masked_fill(self.copy_mask[:T,:T] == 0, 0)\nc = c @ F.one_hot(idx, num_classes = self.config.vocab_size).float()       \nx = self.head(x) + c\n```\n注意：当某个标记在上下文中多次出现时，使用最大概率而不是总概率可能会更好。\n\n# Top-a 采样方法\n\n我们还提出了一种新的采样方法，称为 top-a（见 src\u002Futils.py）：\n\n(1) 找到 softmax 后的最大概率 p_max。\n\n(2) 移除所有概率低于 0.2 * pow(p_max, 2) 的条目。因此它是自适应的，这就是“top-a”的由来。\n\n(3) 你可以自由调整 0.2 和 2 这两个系数。建议先从调整 0.2 开始。\n\nTop-a 的思路是：\n\n1. 如果 max_prob=0.9，则移除所有概率 \u003C 0.162 的标记（即排除所有其他选择）。\n2. 如果 max_prob=0.5，则移除所有概率 \u003C 0.05 的标记（即允许更多选择）。\n3. 如果 max_prob=0.1，则移除所有概率 \u003C 0.002 的标记（即保留大量可能性）。\n\n```\nprobs = F.softmax(logits, dim=-1)\n\nlimit = torch.pow(torch.max(probs), 2) * 0.02\nlogits[probs \u003C limit] = -float('Inf')\n```\n\n# 性能\n\nSimpleBooks-92 数据集上的字符级别损失 https:\u002F\u002Fdldata-public.s3.us-east-2.amazonaws.com\u002Fsimplebooks.zip\n\n![RWKV-vs-MHA](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_f17494bae4b0.png)\n\n灰色：普通 MHA+Rotary+GeGLU——性能一般。17.2M 参数。\n\n红色：RWKV（“线性”注意力）——显存友好——在长上下文窗口时速度更快——性能良好。16.6M 参数。\n\n绿色：MHA+Rotary+GeGLU+Token_shift。17.2M 参数。\n\n蓝色：MHA_pro（带有各种改进和 RWKV 类型 FFN 的 MHA）——速度较慢——需要更多显存——性能不错。16.6M 参数。\n\n```\n@software{peng_bo_2021_5196578,\n  author       = {PENG Bo},\n  title        = {BlinkDL\u002FRWKV-LM: 0.01},\n  month        = aug,\n  year         = 2021,\n  publisher    = {Zenodo},\n  version      = {0.01},\n  doi          = {10.5281\u002Fzenodo.5196577},\n  url          = {https:\u002F\u002Fdoi.org\u002F10.5281\u002Fzenodo.5196577}\n}\n```\n\n# 初始化\n\n我们对 RWKV 使用了精心设计的初始化方法，以实现快速收敛——采用适当缩放的正交矩阵，并结合特殊的 time_w 曲线。详细信息请参阅 model.py 文件。\n\n一些学习到的 time_w 示例：\n\n![RWKV-time-w](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_readme_463461d33ea5.png)","# RWKV-LM 快速上手指南\n\nRWKV 是一种结合了 RNN 的高效推理与 Transformer 级别性能的新型架构。最新版本的 **RWKV-7 \"Goose\"** 具备线性时间复杂度、恒定显存占用（无需 KV Cache）且无注意力机制，非常适合大语言模型及多模态应用。\n\n## 1. 环境准备\n\n在开始之前，请确保您的开发环境满足以下要求：\n\n*   **操作系统**: Linux (推荐) 或 Windows\n*   **Python 版本**: 3.10 或更高\n*   **PyTorch 版本**: 2.5 或更高\n*   **CUDA 版本**: 12.4 或更高 (用于 GPU 加速)\n*   **关键依赖约束**: 必须使用 `pytorch-lightning==1.9.5`，其他库建议使用最新版。\n*   **硬件建议**:\n    *   **训练**: 参考配置仅需单张 10GB 显存的 GPU (可通过减小 batch size 适配更低显存)。高性能训练推荐多卡 H100\u002FA100。\n    *   **推理**: 支持从移动端到 RTX 4090\u002F5090 等各类设备。\n\n> **国内开发者提示**: 如遇网络问题，建议配置 pip 国内镜像源（如清华源、阿里源）加速依赖下载。\n\n## 2. 安装步骤\n\n### 2.1 安装基础依赖\n\n首先升级 PyTorch 并安装核心训练依赖。以下命令以 CUDA 12.1 为例（请根据实际环境调整 `cu121` 为对应版本，如 `cu124`）：\n\n```bash\n# 升级 PyTorch (示例为 cu121，请根据实际情况替换 extra-index-url)\npip install torch --upgrade --extra-index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu121\n\n# 安装核心依赖，注意锁定 pytorch-lightning 版本\npip install pytorch-lightning==1.9.5 deepspeed wandb ninja --upgrade\n```\n\n### 2.2 获取代码与模型权重\n\n克隆官方仓库并进入 RWKV-7 的参考实现目录：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM.git\ncd RWKV-LM\u002FRWKV-v7\u002Ftrain_temp\n```\n\n如果您需要直接进行推理测试，也可以安装 Python SDK：\n\n```bash\npip install rwkv\n```\n\n## 3. 基本使用\n\n### 3.1 快速训练演示 (基于 MiniPile 数据集)\n\n官方提供了简化的训练脚本，可在单卡上快速验证流程。\n\n**第一步：准备数据与初始化权重**\n运行预处理脚本，它将下载 MiniPile 数据集 (.bin\u002F.idx) 并生成初始权重文件 `rwkv-init.pth`。\n\n```bash\nsh .\u002Fdemo-training-prepare.sh\n```\n\n**第二步：启动训练**\n运行训练脚本。建议先登录 Weights & Biases (`wandb login`) 以监控训练过程，但这步不是强制的。\n\n```bash\nsh .\u002Fdemo-training-run.sh\n```\n\n训练开始后，观察 `out\u002F........\u002Ftrain_log.txt`，正常的 Loss 下降曲线应如下所示：\n```text\n0 4.875856 131.0863 ...\n1 4.028621 56.1834 ...\n2 3.801625 44.7739 ...\n...\n```\n\n> **重要训练提示**:\n> *   **权重衰减 (Weight Decay)**: 仅对大型矩阵参数（主要是投影层，代码中标注了 `wdecay`）应用权重衰减，**不要**对所有参数应用，否则性能会显著下降。\n> *   **归一化**: RWKV-7 必须使用 **PreLN LayerNorm**，而非 RMSNorm。\n> *   **初始化**: 严格遵循参考代码中的初始化策略，不同参数有不同的初始化方式和学习率倍率。\n\n### 3.2 模型推理\n\n您可以使用官方提供的 Demo 脚本进行推理测试，或使用已安装的 `rwkv` 包。\n\n**方式 A: 运行官方 Demo 脚本**\n在 `RWKV-v7` 目录下，提供了三种模式的演示：\n\n```bash\n# GPT 模式 (标准生成)\npython rwkv_v7_demo.py\n\n# RNN 模式 (状态传递)\npython rwkv_v7_demo_rnn.py\n\n# 混合模式 (最快)\npython rwkv_v7_demo_fast.py\n```\n\n**方式 B: 使用 Python SDK 推理**\n如果您安装了 `rwkv` 包，可以在 Python 中直接加载模型（需自行下载 `.pth` 或 `.gguf` 权重）：\n\n```python\nfrom rwkv.model import RWKV\n\n# 加载模型 (示例路径，请替换为实际下载的权重路径)\nmodel = RWKV(model='\u002Fpath\u002Fto\u002Frwkv-7-world-7b.pth', strategy='cuda fp16')\n\n# 生成文本\noutput, state = model.forward([1234, 5678], None) # 输入为 token IDs\n```\n\n### 3.3 数据处理 (自定义数据集)\n\n若需使用自己的 JSONL 数据进行训练（如 SFT），请使用官方工具转换为 binidx 格式：\n\n```bash\n# 将 jsonl 转换为 binidx\npython ..\u002FRWKV-v5\u002Fmake_data.py your_data.jsonl\n\n# 计算训练所需的 magic_prime 和 exit_tokens 参数\npython ..\u002FRWKV-v5\u002Fcompute_magic_prime.py your_data.bin\n```\n\n在训练命令中，使用计算出的 `--my_exit_tokens` 和 `--magic_prime` 参数来精确控制训练步数。","某初创团队正在开发一款运行在旧款安卓手机上的离线法律助手，需要处理长达数百页的合同文档并实时回答用户提问。\n\n### 没有 RWKV-LM 时\n- **显存爆炸导致崩溃**：传统 Transformer 架构依赖 KV Cache，随着合同上下文变长，显存占用线性增长，直接撑爆移动端有限的内存，导致应用频繁闪退。\n- **响应速度随长度下降**：输入文档越长，推理延迟越高，用户等待答案的时间从几秒拖延至数十秒，完全无法满足“实时问答”的体验要求。\n- **云端依赖成本高**：为了规避本地算力不足，团队被迫将请求转发至云端 GPU 集群，不仅增加了服务器成本，还引发了法律数据出域的隐私合规风险。\n- **长文理解能力割裂**：受限于上下文窗口，不得不采用滑动窗口或摘要策略，导致模型无法关联合同首尾的关键条款，回答准确性大打折扣。\n\n### 使用 RWKV-LM 后\n- **恒定显存稳定运行**：RWKV-LM 作为线性时间、常数空间的 RNN 架构，无需 KV Cache，无论合同多长，显存占用始终固定，在旧款手机上也能流畅运行。\n- **极速推理体验一致**：得益于其并行训练与高效推理特性，即使在生成长篇分析时，生成速度依然保持每秒上百 token 的恒定高速，用户几乎无感知延迟。\n- **纯本地部署保隐私**：凭借高效的移动端推理库，整个大模型可完整植入手机本地，彻底切断云端依赖，确保敏感法律数据不出设备，合规且零流量成本。\n- **无限上下文精准洞察**：支持无限上下文长度（infinite ctx_len），模型能一次性“读透”整本百页合同，精准捕捉跨段落的逻辑漏洞，提供专家级的审查建议。\n\nRWKV-LM 通过打破显存与速度的瓶颈，让超大上下文的大语言模型真正得以在资源受限的边缘设备上落地生根。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FBlinkDL_RWKV-LM_609f0b08.png","BlinkDL","PENG Bo","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002FBlinkDL_14ff3f9b.jpg","RWKV is all you need",null,"BlinkDL_AI","https:\u002F\u002Frwkv.com\u002F","https:\u002F\u002Fgithub.com\u002FBlinkDL",[81,85,89,93],{"name":82,"color":83,"percentage":84},"Python","#3572A5",86.8,{"name":86,"color":87,"percentage":88},"Cuda","#3A4E3A",8.8,{"name":90,"color":91,"percentage":92},"C++","#f34b7d",2.5,{"name":94,"color":95,"percentage":96},"Shell","#89e051",1.9,14451,1000,"2026-04-03T16:40:13","Apache-2.0","Linux, Windows","训练必需 NVIDIA GPU。参考配置：单卡 10GB+ VRAM 可运行默认配置；高性能训练需多卡 H100；推理支持 RTX 5090 等。CUDA 12.4+。","未说明",{"notes":105,"python":106,"dependencies":107},"1. 必须严格使用 pytorch-lightning==1.9.5 版本，即使 PyTorch 和 CUDA 可以升级。2. 训练 RWKV-7 时，权重衰减 (weight decay) 仅应用于大型矩阵参数，否则性能会大幅下降。3. 必须使用 PreLN LayerNorm 而非 RMSNorm。4. 官方参考实现位于 RWKV-v7\u002Ftrain_temp 目录。5. Windows 和 Office 已集成 RWKV 运行时。","3.10+",[108,109,110,111,112],"torch>=2.5","pytorch-lightning==1.9.5","deepspeed","wandb","ninja",[14,13,35],[115,116,117,118,119,120,121,122,123,124,125,126,127,128],"attention-mechanism","deep-learning","gpt","gpt-2","gpt-3","language-model","linear-attention","lstm","pytorch","rnn","transformer","transformers","rwkv","chatgpt","2026-03-27T02:49:30.150509","2026-04-11T18:33:06.355258",[132,137,142,147,152],{"id":133,"question_zh":134,"answer_zh":135,"source_url":136},15018,"当上下文长度（Ctx Length）超过 2000 时出现 CUDA 编译错误怎么办？","新的 RWKV-4 版本已经支持编译上下文长度为 4096 的内核。如果您遇到此错误，请升级到最新的 RWKV-4 版本。此外，当前设计在 FP16 精度下可能会溢出，作者正在开发新的内核以解决此问题，建议等待更新或使用支持的配置。","https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F6",{"id":138,"question_zh":139,"answer_zh":140,"source_url":141},15019,"如何获取和使用 RWKV 模型的嵌入向量（Embeddings）进行训练或对比学习？","您可以参考 `gptcache` 库中的实现代码来提取嵌入向量。该库提供了直接用于 RWKV 的嵌入函数，代码非常简洁。您可以查看以下文档获取具体实现：https:\u002F\u002Fgptcache.readthedocs.io\u002Fen\u002Flatest\u002F_modules\u002Fgptcache\u002Fembedding\u002Frwkv.html。目前也有用户在 Hugging Face Transformers 中实现了相关功能。","https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F24",{"id":143,"question_zh":144,"answer_zh":145,"source_url":146},15020,"训练时报错 'assert fragment_start \u003C fragment_end' 如何解决？","这个错误通常是因为模型中某个参数的形状不正确，例如出现了大小为 0 的张量（如 `torch.randn(0)`）。具体原因往往是 PyTorch 模型列表中没有包含任何参数，例如代码中写成了 `feedforward = nn.ModuleList([nn.Linear(a,b) for i in range(0)])`（range 为 0 导致列表为空）。请检查您的模型定义代码，确保层数或参数范围设置正确，避免生成空参数列表。","https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F149",{"id":148,"question_zh":149,"answer_zh":150,"source_url":151},15021,"如何将 RWKV 模型转换为 Hugging Face 格式以便在 Transformers 中使用？","您可以使用官方提供的转换脚本。通常需要准备原始的 `rwkv.pth` 权重文件和 `convert_rwkv_checkpoint_to_hf.py` 转换脚本。运行脚本后，它将生成标准的 Hugging Face 文件结构，包括 `config.json`, `generation_config.json`, 分片的 `pytorch_model-*.bin` 文件以及 tokenizer 相关文件。转换后的模型可以直接上传到 Hugging Face Hub 或使用 `from_pretrained` 加载。","https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F113",{"id":153,"question_zh":154,"answer_zh":155,"source_url":156},15022,"在使用 ChatRWKV 加载大型模型（如 14B）时出现段错误（Segmentation Fault）怎么办？","请更新到最新版本的 ChatRWKV v2 和 rwkv pip 包（版本 0.7.0 或更高）。新版本引入了 `v2\u002Fconvert_model.py` 脚本，建议在加载前先用该脚本将模型转换为特定策略（strategy）格式。这样可以显著加快加载速度并节省 CPU 内存，从而避免在流式加载或分割加载大模型时发生段错误。","https:\u002F\u002Fgithub.com\u002FBlinkDL\u002FRWKV-LM\u002Fissues\u002F44",[158,163,168,173,178],{"id":159,"version":160,"summary_zh":161,"released_at":162},81844,"5.00","RWKV v5 稳定版","2023-12-16T10:44:17",{"id":164,"version":165,"summary_zh":166,"released_at":167},81845,"4.00","只是一个稳定版。","2022-12-06T00:28:49",{"id":169,"version":170,"summary_zh":171,"released_at":172},81846,"2.00","所附模型：ctx1024-layer6-emb512，在enwik8数据集上，验证集困惑度为1.65（0.72 bit\u002F字符）。","2022-03-25T17:20:03",{"id":174,"version":175,"summary_zh":176,"released_at":177},81847,"0.02","v0.02，包含RWKV、MHA_shift、MHA_rotary、MHA_pro以及时间移位混合。","2021-08-25T15:05:54",{"id":179,"version":180,"summary_zh":181,"released_at":182},81848,"0.01","首次发布，支持 RWKV、MHA_rotary、MHA_pro 以及时移混合。","2021-08-13T15:58:28"]