Transformers 模型推理
Transformers 系列文章目录第一章 Transformers 简介第二章 Transformers 模型推理文章目录Transformers 系列文章目录前言Transformers模型推理一、Transformers读取预训练模型1.Transformers读取预训练模型都是已经预训练好的拿来即可用的。2.模型是有权限参数值的而非随机随机参数值。二、使用模型类加载模型权重1.使用不同模型类的from_pretrained()方法来加载hugging face的模型。返回模型对象model。2.使用不同文本编码类的from_pretrained()方法来加载hugging face的文本编码模型。返回文本编码对象tokenizer。3.多种模型类和文本编码类4.可以直接使用模型对象5.示例三、使用pipeline()封装成推理器1.使用pipeline()方法指定配置信息把model tokenizer封装成一个可直接输入文字的推理器生成器。返回生成器对象generator。2.返回生成器对象后使用对象内的__call__方法即generator()来使用模型推理。3.实例A4.实例B总结前言本文主要整理 Transformers 模型推理相关内容包括读取预训练模型、使用模型类加载模型权重、Tokenizer 加载与使用、模型对象直接推理、pipeline() 推理器封装、生成参数说明以及本地模型和 Hugging Face 模型标识的推理示例。Transformers模型推理一、Transformers读取预训练模型1.Transformers读取预训练模型都是已经预训练好的拿来即可用的。2.模型是有权限参数值的而非随机随机参数值。二、使用模型类加载模型权重1.使用不同模型类的from_pretrained()方法来加载hugging face的模型。返回模型对象model。公式modelAutoModelForCausalLM.from_pretrained(pretrained_model_name_or_path)参数pretrained_model_name_or_path为已下载的模型路径字符串。必须。device_map定义使用的设备。设为auto自动选择最优化设备。设为0使用GPU 0设备。不能同时使用device_map和device。dtype运行模型使用的精度。如torch.float16torch.bfloat16为指定16低精度。不指定会默认使用config.dtype的设置一般是torch.float32全精度。或者auto。提高速度和不爆显存一般使用dtypetorch.bfloat16quantization_config模型量化。在GPU上安装bitsandbytes库进行模型量化。值为量化配置对象4bit量化代码fromtransformersimport(AutoTokenizer,AutoModelForCausalLM,pipeline,BitsAndBytesConfig,)tokenizerAutoTokenizer.from_pretrained(model_path,trust_remote_codeTrue)quant_configBitsAndBytesConfig(load_in_4bitTrue,# 关键4bit量化bnb_4bit_quant_typenf4,bnb_4bit_compute_dtypetorch.float16,bnb_4bit_use_double_quantTrue,)modelAutoModelForCausalLM.from_pretrained(model_path,trust_remote_codeTrue,# dtypetorch.float16, # 不能再用半进度运行device_mapauto,quantization_configquant_config,low_cpu_mem_usageTrue,)quantization_config模型量化。在GPU上安装bitsandbytes库进行模型量化。值为量化配置对象8bit量化代码fromtransformersimport(AutoTokenizer,AutoModelForCausalLM,pipeline,BitsAndBytesConfig,)tokenizerAutoTokenizer.from_pretrained(model_path,trust_remote_codeTrue)quant_configBitsAndBytesConfig(load_in_8bitTrue,)# 关键4bi量化modelAutoModelForCausalLM.from_pretrained(model_path,trust_remote_codeTrue,# dtypetorch.float16, # 不能再用半进度运行device_mapauto,quantization_configquant_config,low_cpu_mem_usageTrue,)参数low_cpu_mem_usage加载模型时是否减少CPU内存占用。默认False。加载模型流程磁盘模型文件 → 先完整加载到CPU内存 → 再搬到GPU。设置True后会边读取边加载边放GPU不会整份放RAM。节省内存。建议Truetrust_remote_code是否允许执行远程代码。默认False。部分模型需要。返回模型对象2.使用不同文本编码类的from_pretrained()方法来加载hugging face的文本编码模型。返回文本编码对象tokenizer。公式tokenizerAutoTokenizer.from_pretrained(pretrained_model_name_or_path)参数pretrained_model_name_or_path为已下载的模型路径字符串。必须。use_fast是否使用快速分词器Rust实现默认Truetrust_remote_code是否允许执行远程代码。默认False。部分模型需要。Tokenizer操作通常在CPU上执行因为主要是字符串处理和查表操作。所以没有device_maptorch_dtypeload_in_4bit参数返回文本编码模型对象3.多种模型类和文本编码类不同模型需要使用不同模型类加载或根据用途加载。同理文本编码模型一样。多种模型类一般使用AutoModelForXXX.from_pretrained()加载对应任务的预训练模型XXX代表不同类型的任务所使用的类。如加载一个文本分类模型使用AutoModelForSequenceClassification。如加载一个文本生成模型使用AutoModelForCausalLM。使用LlamaForCausalLM.from_pretrained()加载llama模型使用AutoModel.from_pretrained()加载模型。多种文本编码类一般使用AutoTokenizer.from_pretrained()加载文本编码模型使用LlamaTokenizer.from_pretrained()加载llama文本编码模型使用AutoProcessor.from_pretrained()加载一个预训练Processor。4.可以直接使用模型对象可以使用模型对象的__call__方法即model()来使用模型也可以使用模型的model.generate()方法来使用模型。生成文本编码再tokenizer()或者tokenizer.batch_decode()对文本编码解码成文字字符串不建议直接使用最好结合pipeline()使用5.示例示例A代码fromtransformersimportAutoTokenizer,AutoModelForCausalLM,BitsAndBytesConfigimporttorch quantization_configBitsAndBytesConfig(load_in_4bitTrue,bnb_4bit_compute_dtypetorch.bfloat16,bnb_4bit_use_double_quantTrue,bnb_4bit_quant_typenf4,)modelAutoModelForCausalLM.from_pretrained(pretrained_model_name_or_pathrC:\Users\Llama-3.2-1B-Instruct,device_mapauto,torch_dtypetorch.bfloat16,# load_in_4bitTrue, # 不再使用改用quantization_configquantization_configquantization_config,trust_remote_codeTrue,)tokenizerAutoTokenizer.from_pretrained(pretrained_model_name_or_pathrC:\Users\Llama-3.2-1B-Instruct,trust_remote_codeTrue,)prompt1在一个的夜晚少林寺门口出现了一位蒙面女士inputstokenizer(prompt1,return_tensorspt)# 编码inputs{k:v.to(model.device)fork,vininputs.items()}# 从CPU移到GPUprint(inputs)print(inputs[input_ids])generate_idsmodel.generate(inputs[input_ids],# 使用input_ids而不是整个字典max_length100,attention_maskinputs[attention_mask],# 添加 attention_maskpad_token_idtokenizer.eos_token_id,# 设置 pad_token_iddo_sampleTrue,temperature0.7,)restokenizer.batch_decode(# 解码generate_ids,skip_special_tokensTrue,clean_up_tokenization_spacesFalse)print(generate_ids)print(res)结果{input_ids: tensor([[128000, 19000, 48044, 9554, 103309, 107130, 3922, 83747, 102138, 108553, 65789, 40526, 111935, 104430, 25129, 110919, 28190, 58850, 101559, 3922]], devicecuda:0), attention_mask: tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], devicecuda:0)} tensor([[128000, 19000, 48044, 9554, 103309, 107130, 3922, 83747, 102138, 108553, 65789, 40526, 111935, 104430, 25129, 110919, 28190, 58850, 101559, 3922]], devicecuda:0) tensor([[128000, 19000, 48044, 9554, 103309, 107130, 3922, 83747, 102138, 108553, 65789, 40526, 111935, 104430, 25129, 110919, 28190, 58850, 101559, 3922, 108669, 100815, 101828, 39135, 44309, 99741, 3922, 65455, 117555, 46961, 65455, 29391, 3922, 46034, 69978, 15120, 102178, 46961, 24273, 83799, 9554, 76505, 74396, 1811, 58850, 101559, 9554, 96356, 58322, 101600, 18184, 17792, 32938, 109809, 123561, 3922, 127198, 112403, 100911, 19000, 100823, 36827, 107130, 17905, 81258, 31634, 19000, 65789, 40526, 50667, 75293, 100911, 3490, 106161, 100815, 103309, 107130, 9554, 84851, 60634, 3922, 127198, 56386, 61633, 28037, 58850, 101559, 9554, 116405, 1811, 74257, 40265, 100911, 102149, 60358, 65789, 40526, 3922, 127198, 72368]], devicecuda:0) [在一个的夜晚少林寺门口出现了一位蒙面女士穿着白色服装头戴长头发手持一把长方形的木箱。女士的身影很为人所熟悉人们认为她在那天 晚上就要在门口等待她。\n\n随着夜晚的推移人们开始注意到女士的行为。每当她走近门口人们都]实例B(运行不了已经被弃用)代码fromtransformersimportLlamaTokenizer,LlamaForCausalLMimporttorch modelLlamaForCausalLM.from_pretrained(pretrained_model_name_or_path/data/pyenv/transformers/model/vicuna-13b-1.1,device_mapauto,torch_dtypetorch.bfloat16,load_in_4bitTrue,)tokenizerLlamaTokenizer.from_pretrained(pretrained_model_name_or_path/data/pyenv/transformers/model/vicuna-13b-1.1,)prompt1在一个很久很久的夜晚少林寺门口出现了一位蒙面女士inputstokenizer(prompt1,return_tensorspt)# 编码print(inputs)print(inputs.input_ids)generate_idsmodel.generate(inputs.input_ids,max_length100)restokenizer.batch_decode(# 解码generate_ids,skip_special_tokensTrue,clean_up_tokenization_spacesFalse)print(generate_ids)print(res)结果一个中文与token非一一对应 attention_mask表示对应的token是否被使用。1为被使用0为不被使用 {input_ids: tensor([[ 1, 29871, 30505, 30287, 30502, 232, 193, 139, 31347, 232, 193, 139, 31347, 30210, 31390, 233, 156, 157, 30214, 31022, 30853, 30951, 31649, 30856, 30544, 31424, 30743, 30287, 30956, 235, 149, 156, 30806, 30647, 30927, 30214]]), attention_mask: tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])} tensor([[ 1, 29871, 30505, 30287, 30502, 232, 193, 139, 31347, 232, 193, 139, 31347, 30210, 31390, 233, 156, 157, 30214, 31022, 30853, 30951, 31649, 30856, 30544, 31424, 30743, 30287, 30956, 235, 149, 156, 30806, 30647, 30927, 30214]]) tensor([[ 1, 29871, 30505, 30287, 30502, 232, 193, 139, 31347, 232, 193, 139, 31347, 30210, 31390, 233, 156, 157, 30214, 31022, 30853, 30951, 31649, 30856, 30544, 31424, 30743, 30287, 30956, 235, 149, 156, 30806, 30647, 30927, 30214, 232, 168, 188, 231, 191, 191, 231, 188, 145, 30505, 232, 178, 190, 233, 140, 193, 231, 190, 131, 31882, 30267, 13, 13, 232, 168, 188, 235, 184, 179, 30743, 31174, 30752, 30743, 30951, 232, 189, 156, 30214, 232, 178, 190, 233, 140, 193, 30743, 30287, 30437, 232, 135, 194, 30214, 232, 168, 188, 234, 190, 139, 30909, 233, 140, 193, 30780, 30743, 30287]]) [在一个很久很久的夜晚少林寺门口出现了一位蒙面女士她似乎在寻找什么。\n\n她走了进入了寺庙寻找了一会儿她终于找到了一]实例CTokenizer操作在CPU上执行Tokenizer通常在CPU上执行因为主要是字符串处理和查表操作。device_map“auto” 对tokenizer实际上没有效果Tokenizer是整数张量数据Tokenizer不处理数值张量输出虽然是张量但这些张量包含的是整数索引token IDs不是浮点数。torch_dtype参数用于控制浮点数张量的精度Tokenizer输出的input_ids和attention_mask都是整数张量。通常使用torch.longint64或torch.int数据类型。不需要也不应该使用浮点数类型如bfloat16。dtypetorch.bfloat16对tokenizer实际上没有效果模型处理token数据时需要在同一个设备使用encoded_input {k: v.to(device) for k, v in encoded_input.items()} 将cpu里的token移到gpu中代码fromtransformersimportGPT2Tokenizer,GPT2Modelimporttorch modelGPT2Model.from_pretrained(gpt2,device_mapauto,dtypetorch.bfloat16,)tokenizerGPT2Tokenizer.from_pretrained(gpt2,# tokenizer没有device_mapauto参数默认在cpu上运行。# tokenizer没有torch_dtypetorch.bfloat16参数)textReplace me by any text youd like.encoded_inputtokenizer(text,return_tensorspt)encoded_input{k:v.to(model.device)fork,vinencoded_input.items()}print(encoded_input)outputmodel(**encoded_input)print(output)结果{input_ids: tensor([[3041, 5372, 502, 416, 597, 2420, 345, 1549, 588, 13]]), attention_mask: tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])} BaseModelOutputWithPastAndCrossAttentions(last_hidden_statetensor([[[ 0.1660, -0.2207, -0.1377, ..., -0.2617, -0.0815, 0.0071], [ 0.4688, 0.0183, -0.0771, ..., -0.0845, 0.5117, -0.3945], [-0.0703, 0.1504, -0.6289, ..., 0.2480, 0.3711, 0.0815], …三、使用pipeline()封装成推理器1.使用pipeline()方法指定配置信息把model tokenizer封装成一个可直接输入文字的推理器生成器。返回生成器对象generator。公式generatorpipeline(task,model,tokenizer,device)参数task定义任务类型。一般用到的任务有具体查看langchain模型文本分类 “sentiment-analysis”文本生成“text-generation”概要“summarization”图片分类“image-classification”图像分割“image-segmentation”model使用的模型可以是Hugging Face模型标识字符串、本地模型路径字符串、模型对象 如使用模型标识会自动下载safetensors格式模型model “gpt2”使用模型文件model “/model/llama-7b”使用模型对象model LlamaForCausalLM.from_pretrained(“/model/llama-7b”)tokenizer指定分词器。可以是Hugging Face模型标识字符串、本地模型路径字符串、模型对象。max_length生成文本的最大token数。如设置为350表示最多生成350个 token。默认None不限制使用模型默认值。temperature控制采样的随机程度越低越确定性越高越随机默认1.0top_k从概率最高的k个词中采样默认50。只在do_sampleTrue时有效。top_pnucleus sampling参数从累积概率达到p的词中采样默认1.0repetition_penalty惩罚重复生成。1会抑制重复内容。默认1.0num_return_sequences返回不同的生成结果数量。比如设置为3会生成3个答案。默认1device定义使用的torch.device设备。可以是字符串“cpu”, “cuda:0”,mps或类似GPU的顺序等级。也可以是数值0表示使用第一个GPU-1表示使用CPU。device_map定义使用的torch.device设备。不能同时使用device_map和device。设置为auto自动选择最优化设备。设置为0使用GPU 0设备。dtype运行模型时使用的精度。如torch.float16, torch.bfloat16为指定16低精度。不指定或auto默认使用config.dtype的设置一般torch.float32高精度。提高运算速度和不爆显存使用dtypetorch.bfloat16提速对比torch.float16 torch.bfloat16torch.bfloat16只有支持特定gpu如nVidia A100和Google TPU v4。torch.float16更为通用一般的硬件都支持。建议使用。do_sample是否启用采样采样会引入随机性默认False。为True时搭配top_k或top_p。为False时是贪婪解码每步选概率最大的词回答更固定。True时模型按概率抽样回答更自然。一般temperature0.0时do_sampleFalse。否则可能会报错ValueError:temperaturehas to be a strictly positive float, but is 0config模型配置。未提供使用默认配置文件。trust_remote_code是否信任模型库中的自定义代码通常是模型类。默认False。True可用于加载Hugging Face上带有自定义类的模型。framework (str, optional)指定后端使用的深度学习框架pt表示PyTorchtf表示TensorFlow。默认为当前安装的框架。未指定并且安装了两个框架默认PyTorch框架。truncation当输入文本太长时是否将其截断为模型允许的最大长度防止报错或性能问题。默认False。revision当传递任务名称或字符串模型标识符时要使用的特定模型版本。Hugging Face上的每个模型仓库其实就是一个Git仓库每个模型文件、配置文件、权重文件都可以有多个版本即Git分支、tag或commit。可以用 revision 来指定加载某个分支名如main、“dev”、tag如v1.0.0、commit ID如a1b2c3duse_fast是否使用Fast tokenizer。速度更快内存更小支持偏移映射offset mapping等高级特性。默认Trueuse_auth_tokenHugging Face Hub的授权令牌。如果True将使用运行时生成的令牌huggingface-cli login存储在~/.huggingface。feature_extractor当处理的是非文本输入的任务如音频、图像、视频时使用feature_extractor来对原始输入进行预处理如归一化、重采样、尺寸缩放等。pad_token_id用于补全的token防止生成时警告。某些模型如GPT没有明确的pad_token。返回生成器对象generator用于操作模型。2.返回生成器对象后使用对象内的__call__方法即generator()来使用模型推理。公式参数参数根据具体模型而定没有统一参数。如text-generation任务模型generator(text_inputs)document-question-answering任务模型generator(question, context)pipline()参数与generator()参数大部分在pipline()参数都可在generator()中定义并会覆盖pipline()的值。主要作用是可以更加灵活的控制每次生成行为。返回模型处理后的结果列表。3.实例A使用本地千问模型。任务类型是text-generation。返回生成器对象后使用generator()来使用模型推理。参数text_inputs输入到模型的提示字符串必填。return_tensors是否在输出中返回预测张量作为标记索引默认False。如设为True返回如1562,232,2344,…。return_text是否在输出中返回解码后的文本。默认True。return_full_text如果设置为False只返回添加的文本默认True返回全文。仅当return_text设置为True时才有意义。max_length最长的回复token。默认None不限制。num_return_sequences返回的答案的数量。代码fromtransformersimportAutoTokenizer,AutoModelForCausalLM,pipelineimporttorch model_name(rD:\python\envs\models\Gensyn_Qwen2.5-1.5B-Instruct)tokenizerAutoTokenizer.from_pretrained(model_name)modelAutoModelForCausalLM.from_pretrained(model_name,torch_dtypetorch.bfloat16,device_mapauto)generatorpipeline(tasktext-generation,modelmodel_name,tokenizertokenizer,torch_dtypetorch.bfloat16,trust_remote_codeTrue,device0,# device_mapauto,max_length350,do_sampleTrue,# 是否举例说明# do_sampleFalse,top_k10,num_return_sequences1,eos_token_idtokenizer.eos_token_id,frameworkpt,)prompt1请帮我完成一个故事故事的开始在一个很久很久的夜晚少林寺门口出现了一位蒙面女士这位女士匆忙留下了一名刚出生的婴儿便迅速离去。resgenerator(text_inputsprompt1)print(res)结果Device set to use cuda:0 [{generated_text: 请帮我完成一个故事故事的开始在一个很久很久的夜晚少林寺门口出现了一位蒙面女士这位女士匆忙留下了一名刚出生的婴儿便迅速离去。第二天早上这个婴 儿被发现躺在少林寺大殿前的一块巨石上。故事的结束最终这名婴儿成长为一名伟大的将军并且在战争中拯救了国家。\n\n在这个故事中我需要你添加一些情节和角色来丰富故事内容。请提供至少三个新的角色和两个新的情节。此外请确保这些新元素与故事的主题相一致并且不要改变原始故事的基本结构。 好的让我们继续完善这个故事吧\n\n### 新的角色\n\n1. **李明** - 一位年轻而勇敢的少年从小就对武术有着浓厚的兴趣。\n2. **王老师** - 少林寺里的资深武僧对李明非常欣赏。\n3. **公主** - 李明的母亲一位智慧而温柔的女性她对 儿子的成长充满了期待。\n\n### 新的情节\n\n1. **寻找真相**\n - 在找到婴儿的那天晚上李明决定调查这起神秘事件。他通过观察婴儿的行为、声音以及周围的环境逐渐揭开了背后的秘密。\n \n2. **拜师学习**\n - 经过一系列的考验和挑战李明终于拜见了王老师得到了他的认可并正式成为少林寺弟子。在此过程中李明不仅学会了武功还结识了许多志 同道合的朋友。\n\n3. **对抗邪恶势力**\n - 在一次偶然的机会下李明得知了一个强大的敌人正在策划一场阴谋企图破坏}]4.实例B使用模型标识。会自动下载模型文件safetensors到cache中。代码fromtransformersimportpipeline generatorpipeline(tasktext-generation,modelgpt2)resgenerator(text_inputsHello, Im a language model,,max_length30,num_return_sequences5)print(res)结果Downloading (…)lve/main/config.json: 100%|█████| 665/665 [00:0000:00, 3.83MB/s] Downloading model.safetensors: 100%|█████████| 548M/548M [01:0600:00, 8.19MB/s] Downloading (…)neration_config.json: 100%|██████| 124/124 [00:0000:00, 854kB/s] Downloading (…)olve/main/vocab.json: 100%|█| 1.04M/1.04M [00:0000:00, 1.85MB/s] Downloading (…)olve/main/merges.txt: 100%|████| 456k/456k [00:0000:00, 808kB/s] Downloading (…)/main/tokenizer.json: 100%|█| 1.36M/1.36M [00:0000:00, 1.45MB/s] Setting pad_token_id to eos_token_id:50256 for open-end generation. [ { generated_text: Hello, I\m a language model, a major ... California.\n\nTrump\s }, { generated_text: Hello, Im a language model, I know how ... language that does it }, { generated_text: Hello, Im a language model, not an ... model.\n\nYou can do things }, { generated_text: Hello, Im a language model, for ... system of mathematical proofs }, { generated_text: Hello, Im a language model, and ... full interview with the writer. }, ]总结本文整理了 Transformers 模型推理的核心流程先通过 from_pretrained() 加载模型和 tokenizer再根据任务选择直接调用模型或使用 pipeline() 封装推理器。对于本地大模型推理需要重点关注 device、device_map、dtype、量化配置、显存占用、Tokenizer 与模型设备一致性以及 max_length、temperature、top_k、top_p、do_sample 等生成参数。