Llama 3.2入门基础教程(非常详细),Llama 3.2微调、部署以及多模态训练入门到精通,收藏这一篇就够了!_llama教程
2024年9 月 25 日 Meta 发布了 Llama 3.2,包括 11B 和 90B 的视觉语言模型。
Llama 3技术剖析与部署
相较于Llama2, Llama3的改变其实并不是太大。 Tokenizer变成了128K的词表,使用了GQA,不在是原来的只在Llama2-70B里使用了。所以说,最大的改变就是词表与GQA。然后在训练上变化比较大,参数变大了,400B的还没放出来。但它的训练是变化很大的。训练数据明显比过去多,15T的token数差不多是Llama2的四倍多,而且这个数据的质量明显要高呢。
新的数据过滤器,幻觉、NSFW、语义重复、分类这些都有提高或者新增。
预训练的数据也在变好,再加上适当的优化技术。
所以真的结构上的改变是GQA。
那看一下GQA是咋回事吧。 一切的改进都是针对Transformer的QKV这块来的。
原始的是这样的,每一个QKV的计算都是分别进行的,这样QKV的计算其实要有大量的计算。基本上是一个下面的计算
考虑到这样一个大的计算会有非常大的计算量,于是把这个Attention拆成了小块,然后连接在一起。也就是下面的MHA其实也是一种优化,但是很明显,在LLM变成极大后,这个东西还要再优化,因为它还是消耗了太大的计算量。
于是最早有人想优化成MQA那种,就是一个K、一个V对应所有的Q,这种方式确实很容易扩大QKV的参数规模,同时非常有效的减少KV缓存。但是因为这个参数它太共同了,所以后期要在FFN那块增加相应的参数才成。效果也没有证明好了。
我给大家准备了一份全套的《AI大模型零基础入门+进阶学习资源包》,包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓
于是又有了更优的版本:GQA,所有的优化都是“中庸”嘛,中不偏,庸不易。
于是GQA呢,是简单的把MHA分成几组,每组共用一个就好了。从Llama2-70b,还有Llama3全系来看呢,GQA这个确实是在性能与KV缓存的显存占用上获得了很好的平衡。
谈到这儿,你有没有发现现在讲Llama3,其实是有很多基础的东西,如attention, mha, ffn一类的东西,你可能有些模糊了呢?我非常建议有举的人都去听听由知乎知学堂开设的这门AI大模型公开课,课程带你学习GPT背后的技术原理,LangChain、Fine-tune技术,从理论实践,到深度讲解,带你全程体验微调过程,定制属于自己的大模型。课上还能直接对话AI技术大佬,现场答疑,非常不错。这样你能掌握一套更全面的知识了。
既然这套东西没有什么大的改动,那我们就看看怎么用吧。
通常我们可以这样认为 Prompt是要优先RAG,RAG是要优先微调Finetune的。我们就从部署一个Llama3开始吧。看看怎么用Prompt,再怎么用RAG,再怎么微调Finetune它。
模型基本使用方法
这次我们搞个接地气的,直接用一个大家想不到的模型:中国联通AI创新中心微调的“Unichat-llama3-Chinese-8B”,看看联通的实力如何。毕竟我们用中文更容易看到效果。
运行代码很简单:
import transformersfrom transformers import AutoTokenizer, AutoModelForCausalLMimport torchmodel_id = \"UnicomLLM/Unichat-llama3-Chinese-8B\" #可以是本地路径pipeline = transformers.pipeline( \"text-generation\", model=model_id, model_kwargs={\"torch_dtype\": torch.bfloat16}, device=\"cuda\",)messages = [ {\"role\": \"system\", \"content\": \"A chat between a curious user and an artificial intelligence assistant.The assistant gives helpful, detailed, and polite answers to the user\'s questions.\"}, {\"role\": \"user\", \"content\": \"你是谁\"},]prompt = pipeline.tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True)terminators = [ pipeline.tokenizer.eos_token_id, pipeline.tokenizer.convert_tokens_to_ids(\"\")]outputs = pipeline( prompt, max_new_tokens=2048, eos_token_id=terminators, do_sample=False, temperature=0.6, top_p=1, repetition_penalty=1.05)print(outputs[0][\"generated_text\"][len(prompt):])
理论上你就能运行了,如果不缺支持库(24G显存的运行会顺畅些)
Rag
这事吧,其实也不难,现在的框架已经很丰富了。我们举个例子吧。
通常langchain rag的流程如下
代码吧,搞一份供参考吧:
from langchain.llms.base import LLMfrom typing import Any, List, Optionalfrom langchain.callbacks.manager import CallbackManagerForLLMRunfrom transformers import AutoTokenizer, AutoModelForCausalLM, RagTokenizer, RagRetriever, RagSequenceForGenerationimport torchclass LLaMA3_LLM(LLM): tokenizer: AutoTokenizer = None model: AutoModelForCausalLM = None rag_tokenizer: RagTokenizer = None rag_retriever: RagRetriever = None rag_generator: RagSequenceForGeneration = None def __init__(self, mode_name_or_path :str, rag_name_or_path: str): super().__init__() print(\"正在从本地加载模型和RAG组件...\") self.tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, use_fast=False) self.model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtype=torch.bfloat16, device_map=\"auto\") self.tokenizer.pad_token = self.tokenizer.eos_token # 初始化RAG组件 self.rag_tokenizer = RagTokenizer.from_pretrained(rag_name_or_path) self.rag_retriever = RagRetriever.from_pretrained(rag_name_or_path) self.rag_generator = RagSequenceForGeneration.from_pretrained(rag_name_or_path) print(\"完成本地模型和RAG组件的加载\") def bulid_input(self, prompt, history=[]): user_format=\'user\\n\\n{content}\' assistant_format=\'assistant\\n\\n{content}\' history.append({\'role\':\'user\',\'content\':prompt}) prompt_str = \'\' # 拼接历史对话 for item in history: if item[\'role\']==\'user\': prompt_str+=user_format.format(content=item[\'content\']) else: prompt_str+=assistant_format.format(content=item[\'content\']) return prompt_str def _call(self, prompt : str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any): input_str = self.bulid_input(prompt=prompt) input_ids = self.tokenizer.encode(input_str, add_special_tokens=False, return_tensors=\'pt\').to(self.model.device) # 使用RAG模型进行检索 with torch.no_grad(): retrieved = self.rag_retriever(input_str, return_tensors=\"pt\") generated = self.rag_generator(input_ids=retrieved[\'retrieved_indices\'], attention_mask=retrieved[\'retrieved_attention_mask\']) # 检查是否成功生成了回复 if generated is None: return \"Sorry, I couldn\'t generate a response.\" outputs = generated.sequences.tolist()[0][len(input_ids[0]):] response = self.tokenizer.decode(outputs).strip().replace(\'\', \"\").replace(\'assistant\\n\\n\', \'\').strip() return response @property def _llm_type(self) -> str: return \"LLaMA3_LLM\" from LLM import LLaMA3_LLMllm = LLaMA3_LLM(mode_name_or_path = \"/root/autodl-tmp/LLM-Research/Meta-Llama-3-8B-Instruct\")llm(\"你是谁\")
微调
微调这事,其实主要还是看数据,太少了你也不要有太大期望。不过参考代码还是可以给一下。
首先你的数据是这样的(多个重复):
{ \"instruction\": \"回答以下用户问题,仅输出答案。\", \"input\": \"1+1等于几?\", \"output\": \"2\"}
然后代码差不多是这样的(这次从modelscope下载, 期望你能知道安装相应的库)
import torchfrom modelscope import snapshot_download, AutoModel, AutoTokenizerimport osmodel_dir = snapshot_download(\'LLM-Research/Meta-Llama-3-8B-Instruct\', cache_dir=\'/root/autodl-tmp\', revision=\'master\')def process_func(example): MAX_LENGTH = 384 # Llama分词器会将一个中文字切分为多个token,因此需要放开一些最大长度,保证数据的完整性 input_ids, attention_mask, labels = [], [], [] instruction = tokenizer(f\"user\\n\\n{example[\'instruction\'] + example[\'input\']}assistant\\n\\n\", add_special_tokens=False) # add_special_tokens 不在开头加 special_tokens response = tokenizer(f\"{example[\'output\']}\", add_special_tokens=False) input_ids = instruction[\"input_ids\"] + response[\"input_ids\"] + [tokenizer.pad_token_id] attention_mask = instruction[\"attention_mask\"] + response[\"attention_mask\"] + [1] # 因为eos token咱们也是要关注的所以 补充为1 labels = [-100] * len(instruction[\"input_ids\"]) + response[\"input_ids\"] + [tokenizer.pad_token_id] if len(input_ids) > MAX_LENGTH: # 做一个截断 input_ids = input_ids[:MAX_LENGTH] attention_mask = attention_mask[:MAX_LENGTH] labels = labels[:MAX_LENGTH] return { \"input_ids\": input_ids, \"attention_mask\": attention_mask, \"labels\": labels } tokenizer = AutoTokenizer.from_pretrained(\'/root/autodl-tmp/LLM-Research/Meta-Llama-3-8B-Instruct\', use_fast=False, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(\'/root/autodl-tmp/LLM-Research/Meta-Llama-3-8B-Instruct\', device_map=\"auto\",torch_dtype=torch.bfloat16)config = LoraConfig( task_type=TaskType.CAUSAL_LM, target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\", \"gate_proj\", \"up_proj\", \"down_proj\"], inference_mode=False, # 训练模式 r=8, # Lora 秩 lora_alpha=32, # Lora alaph,具体作用参见 Lora 原理 lora_dropout=0.1# Dropout 比例)args = TrainingArguments( output_dir=\"./output/llama3\", per_device_train_batch_size=4, gradient_accumulation_steps=4, logging_steps=10, num_train_epochs=3, save_steps=100, learning_rate=1e-4, save_on_each_node=True, gradient_checkpointing=True)trainer = Trainer( model=model, args=args, train_dataset=tokenized_id, data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),)trainer.train()lora_path=\'./llama3_lora\'trainer.model.save_pretrained(lora_path)tokenizer.save_pretrained(lora_path)from transformers import AutoModelForCausalLM, AutoTokenizerimport torchfrom peft import PeftModelmode_path = \'/root/autodl-tmp/LLM-Research/Meta-Llama-3-8B-Instruct\'lora_path = \'./llama3_lora\' # lora权重路径# 加载tokenizertokenizer = AutoTokenizer.from_pretrained(mode_path)# 加载模型model = AutoModelForCausalLM.from_pretrained(mode_path, device_map=\"auto\",torch_dtype=torch.bfloat16)# 加载lora权重model = PeftModel.from_pretrained(model, model_id=lora_path, config=config)prompt = \"你是谁?\"messages = [ # {\"role\": \"system\", \"content\": \"现在你要扮演皇帝身边的女人--甄嬛\"}, {\"role\": \"user\", \"content\": prompt}]text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors=\"pt\").to(\'cuda\')generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=512, eos_token_id=tokenizer.encode(\'\')[0])generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]print(response)
多模态训练
可能还要等等,现在的llama3官方还没有提供400B的那个多模态版本。不过GitHub上有个llama-multimodal-vqa的项目,大概的方向是这样的,用一个CLIP把图像编码成了Token,再用Llama3训练一下。但是结果真的不太成啊。还是等官方400b吧。
如何学习AI大模型 ?
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料。包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓
对于0基础小白入门:
如果你是零基础小白,想快速入门大模型是可以考虑的。
一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。
😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓
👉1.大模型入门学习思维导图👈
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程扫描领取哈)
👉2.AGI大模型配套视频👈
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。
👉3.大模型实际应用报告合集👈
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程扫描领取哈)
👉4.大模型落地应用案例PPT👈
光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(全套教程扫描领取哈)
👉5.大模型经典学习电子书👈
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程扫描领取哈)
👉6.大模型面试题&答案👈
截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程扫描领取哈)
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习
这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓