一、模型简介
原子大模型Atom由Llama中文社区和原子回声联合打造,在中文大模型评测榜单C-Eval中位居前十(8月21日评测提交时间)。
Atom系列模型包含Atom-7B和Atom-13B,基于Llama2做了中文能力的持续优化。Atom-7B和Atom-7B-Chat目前已完全开源,支持商用,可在Hugging Face仓库获取模型,详情见Atom-7B下载。
Atom大模型针对中文做了以下优化:
大规模的中文数据预训练
原子大模型Atom在Llama2的基础上,采用大规模的中文数据进行持续预训练,包含百科、书籍、博客、新闻、公告、小说、金融数据、法律数据、医疗数据、代码数据、专业论文数据、中文自然语言处理竞赛数据集等,详见? 数据来源。
同时对庞大的数据进行了过滤、打分、去重,筛选出超过1T token的高质量中文数据,持续不断加入训练迭代中。
更高效的中文词表
为了提高中文文本处理的效率,我们针对Llama2模型的词表进行了深度优化。首先,我们基于数百G的中文文本,在该模型词表的基础上扩展词库至65,000个单词。经过测试,我们的改进使得中文编码/解码速度提高了约350%。此外,我们还扩大了中文字符集的覆盖范围,包括所有emoji符号?。这使得生成带有表情符号的文章更加高效。
自适应上下文扩展
Atom大模型默认支持4K上下文,利用位置插值PI和Neural Tangent Kernel (NTK)方法,经过微调可以将上下文长度扩增到32K。
? 中文数据
我们通过以下数据来优化Llama2的中文能力:
类型 描述 网络数据 互联网上公开的网络数据,挑选出去重后的高质量中文数据,涉及到百科、书籍、博客、新闻、公告、小说等高质量长文本数据。 Wikipedia 中文Wikipedia的数据 悟道 中文悟道开源的200G数据 Clue Clue开放的中文预训练数据,进行清洗后的高质量中文长文本数据 竞赛数据集 近年来中文自然语言处理多任务竞赛数据集,约150个 MNBVC MNBVC 中清洗出来的部分数据集由于自己电脑没有配置独显,想用CPU来跑大模型看看(中间遇到比较多的坑),记录一下完整的过程,给大家予以借鉴。
二、模型下载
1、git hub地址
GitHub - FlagAlpha/Llama2-Chinese: Llama中文社区,最好的中文Llama大模型,完全开源可商用下载源码:GitHub - FlagAlpha/Llama2-Chinese: Llama中文社区,最好的中文Llama大模型,完全开源可商用
2、 可在Atom-7B-Chat Hugging Face仓库获取模型
1)由于hugging face无法直接访问,推荐一个速度较快、好用的“科学上网”工具91merry 科学上网,我买的30/季度,每月100G流量,我百兆带宽实际下载最大能够达到15M/s。
2)把这里面的每一个文件都下载了。(推荐用IDM,浏览器默认的下载没IDM快,总共下载下来大概14G)
三、模型部署
1、单独弄一个大模型的python虚拟环境,避免包冲突
python -m venv llama_env source llama_env/bin/activate # 在 Windows cmd执行 `llama_env\Scripts\activate`
2、下载python相关依赖包
ps:由于github下载的代码里面requirements.txt是基于有独显的场景,按照官网的在纯cpu环境会运行不起来 。
打开PyTorch官网:Start Locally | PyTorch,选择自己对应的环境,会生成相应的命令。
pip3 install torch torchvision torchaudio
安装其它的包
pip install scipy sentencepiece datasets evaluate transformers tensorboard gradio
3、修改有页面的执行代码,可以在浏览器交互的方式运行(Llama2-Chinese\examples\chat_gradio.py文件)
import gradio as gr import time from transformers import AutoTokenizer, AutoModelForCausalLM,TextIteratorStreamer from threading import Thread import torch,sys,os import json import pandas import argparse with gr.Blocks() as demo: gr.Markdown("""<h1><center>智能助手</center></h1>""") chatbot = gr.Chatbot() msg = gr.Textbox() state = gr.State() with gr.Row(): clear = gr.Button("新话题") re_generate = gr.Button("重新回答") sent_bt = gr.Button("发送") with gr.Accordion("生成参数", open=False): slider_temp = gr.Slider(minimum=0, maximum=1, label="temperature", value=0.3) slider_top_p = gr.Slider(minimum=0.5, maximum=1, label="top_p", value=0.95) slider_context_times = gr.Slider(minimum=0, maximum=5, label="上文轮次", value=0,step=2.0) def user(user_message, history): return "", history + [[user_message, None]] def bot(history,temperature,top_p,slider_context_times): if pandas.isnull(history[-1][1])==False: history[-1][1] = None yield history slider_context_times = int(slider_context_times) history_true = history[1:-1] prompt = '' if slider_context_times>0: prompt += '\n'.join([("<s>Human: "+one_chat[0].replace('<br>','\n')+'\n</s>' if one_chat[0] else '') +"<s>Assistant: "+one_chat[1].replace('<br>','\n')+'\n</s>' for one_chat in history_true[-slider_context_times:] ]) prompt += "<s>Human: "+history[-1][0].replace('<br>','\n')+"\n</s><s>Assistant:" input_ids = tokenizer([prompt], return_tensors="pt",add_special_tokens=False).input_ids[:,-512:] generate_input = { "input_ids":input_ids, "max_new_tokens":512, "do_sample":True, "top_k":50, "top_p":top_p, "temperature":temperature, "repetition_penalty":1.3, "streamer":streamer, "eos_token_id":tokenizer.eos_token_id, "bos_token_id":tokenizer.bos_token_id, "pad_token_id":tokenizer.pad_token_id } thread = Thread(target=model.generate, kwargs=generate_input) thread.start() start_time = time.time() bot_message ='' print('Human:',history[-1][0]) print('Assistant: ',end='',flush=True) for new_text in streamer: print(new_text,end='',flush=True) if len(new_text)==0: continue if new_text!='</s>': bot_message+=new_text if 'Human:' in bot_message: bot_message = bot_message.split('Human:')[0] history[-1][1] = bot_message yield history end_time =time.time() print() print('生成耗时:',end_time-start_time,'文字长度:',len(bot_message),'字耗时:',(end_time-start_time)/len(bot_message)) msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then( bot, [chatbot,slider_temp,slider_top_p,slider_context_times], chatbot ) sent_bt.click(user, [msg, chatbot], [msg, chatbot], queue=False).then( bot, [chatbot,slider_temp,slider_top_p,slider_context_times], chatbot ) re_generate.click( bot, [chatbot,slider_temp,slider_top_p,slider_context_times], chatbot ) clear.click(lambda: [], None, chatbot, queue=False) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--model_name_or_path", type=str, help='mode name or path') parser.add_argument("--is_4bit", action='store_true', help='use 4bit model') args = parser.parse_args() tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path,use_fast=False) tokenizer.pad_token = tokenizer.eos_token if args.is_4bit==False: model = AutoModelForCausalLM.from_pretrained(args.model_name_or_path,device_map='auto',torch_dtype=torch.float32,offload_folder='E:\llm\Llama2-Chinese\llama_env\offload') model.eval() else: from auto_gptq import AutoGPTQForCausalLM model = AutoGPTQForCausalLM.from_quantized(args.model_name_or_path,low_cpu_mem_usage=True, use_triton=False,inject_fused_attention=False,inject_fused_mlp=False) streamer = TextIteratorStreamer(tokenizer,skip_prompt=True) if torch.__version__ >= "2" and sys.platform != "win32": model = torch.compile(model) demo.queue().launch(share=False, debug=True,server_name="127.0.0.1")
4、新建一个py文件,可以命令行模式运行
import torch from transformers import AutoTokenizer, AutoModelForCausalLM # 这里面是你下载的Atom-7B-Chat模型的文件位置和添加offload的文件位置,cpu环境下必须要有offload model = AutoModelForCausalLM.from_pretrained('E:\llm\Llama2-Chinese\llama_env\Atom-7B-Chat',device_map='auto',torch_dtype=torch.float32, offload_folder='E:\llm\Llama2-Chinese\llama_env\offload') model =model.eval() tokenizer = AutoTokenizer.from_pretrained('E:\llm\Llama2-Chinese\llama_env\Atom-7B-Chat',use_fast=False) tokenizer.pad_token = tokenizer.eos_token input_ids = tokenizer(['<s>Human: 请帮我写一篇针对中国足球发展的分析\n</s><s>Assistant: '], return_tensors="pt",add_special_tokens=False).input_ids generate_input = { "input_ids":input_ids, "max_new_tokens":512, "do_sample":True, "top_k":50, "top_p":0.95, "temperature":0.3, "repetition_penalty":1.3, "eos_token_id":tokenizer.eos_token_id, "bos_token_id":tokenizer.bos_token_id, "pad_token_id":tokenizer.pad_token_id } generate_ids = model.generate(**generate_input) text = tokenizer.decode(generate_ids[0]) print(text)
四、模型运行
1、运行修改后的Llama2-Chinese\examples\chat_gradio.py文件
python examples/chat_gradio.py --model_name_or_path E:\llm\Llama2-Chinese\llama_env\Atom-7B-Chat
2、由于是只使用cpu,比较吃内存,原先电脑内存16G的情况下跑不起来,跑到50%就奔溃了,后面加了两根16G内存条,组成了48G内存才能跑起来。跑起来占用内存在38G左右。
3、运行后的界面
PS:使用CPU运行大模型还真是吃内存,生成结果的时候也比较慢,建议大家还是上英伟达的显卡的。
接下来想把本地的一些医学数据进行训练,看看结果怎么样。
tokenchatllamabotidecodechatbotllama2llm大模型parsecpuimupromptgradiopython高质量assistantgit数据集transformers预训练hugging facegpt上下文clitransformergithub浏览器语言处理ivapytorchwikipedia文本数据长文本autogptpandas自然语言自然语言处理自适应debugscriptjsonai video generator