Colossal-AI 低成本复现 ChatGPT,此次开源有什么技术亮点?

关注者
49
被浏览
35,564

7 个回答

0.总览

项目详情及开源ChatGPT平替相关的汇总资料请见我们OpenNLP计划的新项目ChatPiXiu:

ChatPiXiu-Open ChatGPT alternatives repo, including implementations, tools and other resources. PiXiu-貔貅,招财进宝之瑞兽,聚知识也招财富!

1.开源ChatGPT平替

以Alpaca和ChatGLM为首,各种开源项目百花齐放

2.基础模型

以LLaMA、GLM、GPT为主,各种基础模型争奇斗艳

3.数据

数据以ChatGPT/GPT4生成为主,大部分为instruction数据,少部分为RLHF数据。

4.训练框架

ColossalAI、DeepSpeed-Chat等开源了完整的ChatGPT复现流程,尤其是RLHF。

1.开源ChatGTP平替

注:若知乎表格显示效果不佳,请转git阅读。

项目 基础模型 机构 数据集 license 介绍 备注
stanford_alpaca
Alpaca
LLaMA stanford alpaca_data Apache-2.0 license An Instruction-following LLaMA Model.
让 OpenAI 的 text-davinci-003 模型以 self-instruct 方式生成 52K 指令样本,SFT
ChatLLaMA LLaMA Nebuly+AI - license 数据集创建、使用 RLHF 进行高效训练以及推理优化。
Chinese-LLaMA-Alpaca LLaMA ymcui - Apache-2.0 license 中文LLaMA&Alpaca大语言模型+本地CPU/GPU部署 (Chinese LLaMA & Alpaca LLMs)
alpaca-lora LLaMA stanford LLaMA-GPT4 dataset Apache-2.0 license LoRA
Chinese-alpaca-lora
Luotuo-Chinese-LLM
LLaMA - LoRA
ChatGLM GLM 清华 1T 标识符的中英双语数据 Apache-2.0 license 监督微调、反馈自助、人类反馈强化学习 PROJECT.md
FastChat
Vicuna
LLaMA 斯坦福、CMU、UC伯克利 ShareGPT Apache-2.0 license SFT,使用GPT-4作为评判标准,结果显示Vicuna-13B在超过90%的情况下实现了与ChatGPT和Bard相匹敌的能力。
Chinese-Vicuna LLaMA - - Apache-2.0 license LoRA
EasyLM
Koala考拉
LLaMA
multi
UC伯克利 ChatGPT数据和开源数据(Open Instruction Generalist (OIG)、斯坦福 Alpaca 模型使用的数据集、Anthropic HH、OpenAI WebGPT、OpenAI Summarization) Apache-2.0 license SFT
ColossalChat LLaMA ColossalAI InstructionWild:104K bilingual datasets LICENSE SFT-RM-RLHF
ChatRWKV RWKV BlinkDL - Apache-2.0 license ChatRWKV is like ChatGPT but powered by RWKV (100% RNN) language model, and open source.
ChatYuan T5 元语智能 PromptClue LICENSE 基于PromptClue进行了监督微调
OpenChatKit GPT-NoX-20B Together+LAION+Ontocord.ai OIG-43M Apache-2.0 license 60亿参数的审核模型,对不合适或者是有害的信息进行过滤
BELLE BloomLLama LianjiaTech 10M-ChatGPT生成的数据 Apache-2.0 license SFT
PaLM-rlhf-pytorch PaLM lucidrains - MIT license RLHF PaLM太大了
dolly GPT-J-6B - - - 参考Alpaca
LMFlow LLaMA OptimalScale An Extensible Toolkit for Finetuning and Inference of Large Foundation Models. Large Model for All.
LLaMA-7B,一张3090耗时 5 个小时
GPTrillion - - - - 1.5万亿,多模态
open_flamingo LLaMA
CLIP
LAION Multimodal C4 MIT license
baize-chatbot LLaMA project-baize 100k dialogs generated by letting ChatGPT chat with itself. GPL-3.0 license LoRA
ChatPiXiu multi 羡鱼智能 - - LoRA 筹备阶段
stackllama LLaMA Hugging Face - - 用RLHF训练LLaMA的实践指南
Lit-LLaMA LLaMA lightening-ai - - 重写重训LLaMA,绕开license 概念阶段
OPT OPT meta - MIT license 当年对标GPT3的模型

2.基础模型

model 架构 机构 数据 license 介绍 备注
LLaMA
GLM
GPT
OPT

3.数据

dataset type 机构 大小 license 介绍 备注
alpaca_data Instruction stanford
alpaca_chinese_dataset - hikariming
Multilingual Instruction Guanaco
alpaca_chinese_dataset carbonz0
0.5M+1M chinese instruction LianjiaTech
shareGPT lm-sys

4.工具

4.1 训练工具&框架


框架 type 机构 兼容性 license 介绍 备注
ColossalAI general hpcaitech Apache-2.0 license Colossal-AI: Making large AI models cheaper, faster, and more accessible支持ChatGPT完整复现
RLHF RL sunzeyeah 基于transformers库实现 - Implementation of Chinese ChatGPT.
SFT、Reward Model和RLHF
trlx RL CarperAI 强大的transformer 强化学习库 MIT license A repo for distributed training of language models with Reinforcement Learning via Human Feedback (RLHF)
不支持自定义预训练模型。
trl RL Hugging Face 基于transformers Apache-2.0 license 只要是基于ransformers 库开发的预训练库,均可适配,强烈推荐
DeepSpeed-Chat general microsoft 基于DeepSpeed Apache-2.0 license 训练速度大幅提升

4.2 部署推理工具&框架

5. ChatPiXiu项目

ChatPiXiu项目正式发车 ,欢迎加入!

ChatPiXiu-Open ChatGPT alternatives repo, including implementations, tools and other resources. PiXiu-貔貅,招财进宝之瑞兽,聚知识也招财富!Good luck!

5.1 开发计划

5.2 加入我们

OpenNLP计划的其他内容尚在筹备中,暂时只开源了本项目和 OpenTextClassification 项目。欢迎大家积极参与ChatPiXiu的建设和讨论,一起变得更强!

加入方式:

  • 项目建设 :可以在前面列出的开发计划中选择自己感兴趣的部分进行开发,建议优先选择高优先级的任务。包括资料调研和算法开发等工作。
  • OpenLLM技术交流群:知识在讨论中发展, QQ群:740679327
  • 技术分享和讨论:输出倒逼输入,欢迎投稿,稿件会同步到本项目的docs目录和知乎专栏OpenNLP. 同时也欢迎大家积极的参与本项目的讨论 https://github.com/catqaq/ChatPiXiu/discussions。

注:目前急需资料调研方面的人力,尤其是基础模型、数据等方面的调研尚不够充分【虽然已经疯狂熬夜了】,欢迎加入!

参考资料

开源ChatGPT替代模型项目整理

zhuanlan.zhihu.com/p/61

平替chatGPT的开源方案

zhuanlan.zhihu.com/p/61

ChatGPT/GPT4开源“平替”汇总

zhuanlan.zhihu.com/p/62

完整版 ChatGPT 克隆方案,开源了!

zhuanlan.zhihu.com/p/61

ColossalChat:完整RLHF平替ChatGPT的开源方案 zhuanlan.zhihu.com/p/61

ChatGPT开源平替来了,开箱即用!前OpenAI团队打造,GitHub刚发布就揽获800+星 zhuanlan.zhihu.com/p/61

LoRA:大模型的低秩适配-最近大火的lora到底是什么东西?为啥stable diffusion和开源ChatGPT复现都在用?

zhuanlan.zhihu.com/p/62 ?

成本不到100美元!UC伯克利再开源类ChatGPT模型「考拉」:数据量大没有用,高质量才是王道

zhuanlan.zhihu.com/p/62

ChatGPT平替方案汇总

zhuanlan.zhihu.com/p/61

微软宣布开源 Deep Speed Chat,可将训练速度提升 15 倍以上,哪些信息值得关注?

zhihu.com/question/5953

总结当下可用的大模型LLMs

zhuanlan.zhihu.com/p/61

先简单的来说colossal框架在解决的问题:

这个框架主打的是少量修改可以提升原始代码的运算效率,降低运算时间。

接下来通过介绍一个案例来讲解目前colossal是如何在修改少量代码的情况下提升训练速度或者是单卡训练上限的。

colissal中的gpt出现在两个部分,一个部分是在另外一个已经镜像的开源工作colossal-example中另外一个是在目前colossal项目中。

目前小编跑通的是colossal-AI中的titan模块的实现。

Colossal-AI可以实现1D矩阵加速2D矩阵加速3D矩阵加速。

titan模块实现了一套英文预训练gpt语言模型的构建。

语料准备为jsonl格式,每一行为一个字段。那我们这里准备的是中文的语料。

{"text": "\u7b2c1\u7ae0\n\u9884\u5907\u77e5\u8bc6\n\u77e5\u8bc6\u76ee\u6807\n1.\u638c\u63e1\u5b89\u5168\u6807\u5fd7\u3002\n2.\u4e86\u89e3\u5b89\u5168\u6587\u660e\u751f\u4ea7\u548c\u201c6S\u201d\u7ba1\u7406\u8981\u6c42\u3002\n3\uff0e\u4e86\u89e3\u94b3\u5de5\uff08\u673a\u68b0\u62c6\u88c5\uff09\u5b9e\u8bad\u573a\u5730\u7684\u8bbe\u5907\u548c\u64cd\u4f5c\u4e2d\u5e38\u7528\u7684\u5de5\u5177\u3001\u91cf\u5177\u548c\u5203\u5177\u3002\n4\uff0e\u4e86\u89e3\u8f66\u5e8a\u52a0\u5de5\u8303\u56f4\u3001\u578b\u53f7\u3001\u89c4\u683c\u548c\u8f66\u5e8a\u4e3b\u8981\u90e8\u4ef6\u7684\u7ec4\u6210\u53ca\u5176\u4f5c\u7528\u3002\n5\uff0e\u638c\u63e1\u5e8a\u978d\uff08\u5927\u62d6\u677f\uff09\u4e2d\u6ed1\u677f\uff08\u4e2d\u62d6\u677f\uff09\u3001\u5c0f\u6ed1\u677f\uff08\u5c0f\u62d6\u677f\uff09\u7684\u8fdb\u9000\u5200\u65b9\u5411\u3002\n6.\u4e86\u89e3\u8f66\u5e8a\u4f20\u52a8\u7cfb\u7edf\u3002\n1.1\u5b89\u5168\u6587\u660e\u64cd\u4f5c\u89c4\u7a0b(6S\u7ba1\u7406\uff09\n\u5b89\u5168\u4fdd\u8bc1\u751f\u4ea7\uff0c\u751f\u4ea7\u5fc5\u987b\u5b89\u5168\u3002\n1.1.1\n\u8ba4\u8bc6\u5e38\u7528\u7684\u5b89\u5168\u56fe\u6807\n\u5e38\u7528\u7684\u5b89\u5168\u56fe\u6807\u5982\u56fe1-1\u6240\u793a\u3002\n0\n\u6d88\u9632\u624b\u52a8\u542f\u52a8\u5668\n\u706b\u8b66\u7535\u8bdd\n\u6d88-\u9632-\u6c34-"}

那么这个中文语料我们是如何构建的呢,接下来我们来从一个txt的文档中尝试构建gpt所需要的训练数据集结构,里面的maxlen参数呢,跟我们在colissal中config文件中的SEQ_LEN = 1024是一致。

maxlen=1024        
filenames = glob.glob('/root/bert4keras/data/machine/*')
for filename in filenames:
            with open(filename) as f:
                    l = f.read()
                    out=""
                    for l_one in l.split("。"):
                        if len(out+l_one+"。") > maxlen:
                            yield out
                            out=""
                        else:
                            out+=l_one+"。"

模块的基础配置是面向双卡环境构建的分布式gpt2、3预训练语言模型的训练代码。

import contextlib
import os
import torch
import torch.nn as nn
from dataset.webtext import WebtextDataset
from titans.model.gpt import GPTLMLoss
import colossalai
import colossalai.utils as utils
from colossalai.context.parallel_mode import ParallelMode
from colossalai.core import global_context as gpc
from colossalai.logging import disable_existing_loggers, get_dist_logger
from colossalai.nn import LinearWarmupLR
from colossalai.trainer import Trainer, hooks
from colossalai.utils import colo_set_process_memory_fraction, is_using_pp
from colossalai.utils.timer import MultiTimer
from colossalai.zero.init_ctx import ZeroInitContext
def calc_local_model_size(model: torch.nn.Module):
    numel_per_device = 0
    for p in model.parameters():
        numel_per_device += p.numel()
    return numel_per_device
VOCAB_SIZE = 50257
def main():
    parser = colossalai.get_default_parser()
    parser.add_argument('--from_torch', default=False, action='store_true')
    parser.add_argument('--use_dummy_dataset', default=False, action='store_true')
    args = parser.parse_args()
    disable_existing_loggers()
    if args.from_torch:
        colossalai.launch_from_torch(config=args.config)
    else:
        colossalai.launch_from_slurm(config=args.config, host=args.host, port=29500, seed=42)
    logger = get_dist_logger()
    data_path = None if args.use_dummy_dataset else os.environ['DATA']
    logger.info(f'Build data loader from path {data_path}', ranks=[0])
    train_ds = WebtextDataset(path=data_path, seq_len=gpc.config.SEQ_LEN)
    train_dataloader = utils.get_dataloader(train_ds,
                                            seed=42,
                                            batch_size=gpc.config.BATCH_SIZE,
                                            pin_memory=True,
                                            shuffle=True,
                                            drop_last=True)
    logger.info('Build model', ranks=[0])
    use_pipeline = is_using_pp()
    use_interleaved = hasattr(gpc.config.model, 'num_chunks')
    use_zero3 = hasattr(gpc.config, 'zero')
    ctx = contextlib.nullcontext()
    if use_zero3:
        ctx = ZeroInitContext(target_device=torch.cuda.current_device(),
                              shard_strategy=gpc.config.zero.model_config.shard_strategy,
                              shard_param=True)
    with ctx:
        model = gpc.config.model.pop('type')(**gpc.config.model)
    if use_pipeline and use_interleaved and not isinstance(model, nn.ModuleList):
        model = nn.ModuleList([model])
    if use_zero3:
        numel = ctx.model_numel_tensor.item()
    else:
        numel = calc_local_model_size(model)
    tflop = numel * gpc.config.BATCH_SIZE * gpc.config.SEQ_LEN \
        * gpc.get_world_size(ParallelMode.MODEL) * gpc.get_world_size(ParallelMode.DATA) * 8 / (1024 ** 4)
    criterion = getattr(gpc.config, 'loss_fn', None)
    if criterion is not None:
        criterion = criterion.type()
    else:
        criterion = GPTLMLoss()
    logger.info('Build optimizer', ranks=[0])
    optimizer = gpc.config.optimizer.pop('type')(model.parameters(), **gpc.config.optimizer)
    lr_scheduler = LinearWarmupLR(optimizer, total_steps=gpc.config.NUM_EPOCHS, warmup_steps=5)
    engine, train_dataloader, _, lr_scheduler = colossalai.initialize(model,
                                                                      optimizer,
                                                                      criterion,
                                                                      train_dataloader=train_dataloader,
                                                                      lr_scheduler=lr_scheduler)
    global_batch_size = gpc.config.BATCH_SIZE * \
        gpc.get_world_size(ParallelMode.DATA) * getattr(gpc.config, "gradient_accumulation", 1)
    logger.info(f'Init done, global batch size = {global_batch_size}', ranks=[0])
    timier = MultiTimer()
    trainer = Trainer(engine=engine, logger=logger, timer=timier)
    hook_list = [
        hooks.LossHook(),
        hooks.LRSchedulerHook(lr_scheduler=lr_scheduler, by_epoch=True),
        hooks.LogMetricByEpochHook(logger),
        hooks.ThroughputHook(ignored_steps=10, tflop_per_step=tflop),
        hooks.LogMetricByStepHook(),
        hooks.LogMemoryByEpochHook(logger),
    trainer.fit(train_dataloader=train_dataloader,
                epochs=gpc.config.NUM_EPOCHS,
                test_interval=1,
                hooks=hook_list,
                display_progress=True,
                return_output_label=False)
if __name__ == '__main__':
    main()

整体的训练代码非常的简介。并清晰的介绍了Colossal中的一些基础功能环节。

为了保障训练后的模型留存,记得在代码最后面加上

# 引入colossalai.utils包
from colossalai.utils import colo_set_process_memory_fraction, is_using_pp, save_checkpoint
# 保存我们进行训练过的参数   
save_checkpoint('模型名称.pt', 1, trainer.engine.model)

在加载部分,我们需要首先定义我们的模型。

在模型启动参数部分我们需要适当修改参数为单卡适配的参数。

位置在titan\configs目录下有两个关于gpt参数设计的py文件,我们来选一个基于zero3优化的gpt2参数的设置来修改参数模型。力争达到显存跟参数的平衡。

from model import GPT2_small_pipeline_hybrid
from colossalai.nn.optimizer import HybridAdam
from colossalai.zero.shard_utils import TensorShardStrategy
BATCH_SIZE = 12
NUM_EPOCHS = 2
SEQ_LEN = 1024
NUM_MICRO_BATCHES = 4
HIDDEN_SIZE = 768
TENSOR_SHAPE = (BATCH_SIZE // NUM_MICRO_BATCHES, SEQ_LEN, HIDDEN_SIZE)
# if you do no want zero, just comment out this dictionary
zero = dict(model_config=dict(tensor_placement_policy='cuda', shard_strategy=TensorShardStrategy()),
            optimizer_config=dict(initial_scale=2**5))
optimizer = dict(
    type=HybridAdam,
    lr=0.000015,
    weight_decay=1e-2,
model = dict(type=GPT2_small_pipeline_hybrid, checkpoint=True, num_chunks=1)
# pipeline parallel: modify integer value for the number of pipeline stages
# tensor parallel: modify size to set the tensor parallel size, usually the number of GPUs per node
# for the current model implementation, mode can only be 1D or None
parallel = dict(