利用大模型解决NLP任务实战学习记录#AI夏令营 #Datawhale #夏令营

一、简单介绍比赛备注

要使用大模型来解决此机器翻译任务,要比自己训练一个任务简单许多,主要有两种解决方案:

  • 直接调用大模型 API 来解决
  • 本地部署大模型进行推理

二、本地部署大模型进行推理

Qwen2-7B-Instruct 模型需要显存 16GB +,如果没有这么大可以尝试其他小一点的模型

2.1. 加载模型

import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'

from transformers import AutoModelForCausalLM, AutoTokenizer#从transformers导入AutoModel和AutoTokenizer
device = "cuda" # the device to load the model onto

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2-7B-Instruct",       #"/mnt/data/xuhu/qwen/Qwen2-7B-Instruct"指定模型的名ID
    torch_dtype="auto",
    device_map="auto"
)

tokenizer = AutoTokenizer.from_pretrained("/mnt/data/xuhu/qwen/Qwen2-7B-Instruct")#下载并加载分词器
  • 第一个参数:“Qwen/Qwen2-7B-Instruct” 是模型名称,如果你是下载到了本地,也可以赋予本地模型所在的地址,这里我们是从hugging face的镜像加载的模型
  • torch_dtype:设置模型中全部 Linear 层的数据格式,可以使用如下把 3232 位的模型线性层参数转换为 1616 位的模型参数,但是除线性层之外的所有参数仍为 3232 位浮点数
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-7B-Instruct", torch_dtype=torch.float16)#下载并加载模型
  • device_map:指定模型的不同部分加载到哪些设备上,"auto"是指自动分配,通常会同时使用多张GPU进行模型加载,如果想指定使用某一张如下:
device_map = {"": 0}  # 空字符串表示整个模型,0表示第一张GPU

我在加载模型过程中出现了如下报错
在这里插入图片描述
在这里插入图片描述
查到此错误是指你在使用low_cpu_mem_usage=True or a device_maprequires Accelerate: pip install accelerate参数时缺少了Accelerate库。Accelerate是一个用于提高计算性能的库,所以它推荐可以使用 pip install accelerate去进行安装,安装后最好重启内核。
在这里插入图片描述
在这里插入图片描述
这里可以看出,报错已经解决,但是代码下载huggingface速度好像有点慢。需要耐心等待,或许有其他解决办法提速,但是博主比较懒了。。。

  • List item pretrained_model_name_or_path( str 或 os.PathLike ,可选) :是在 Huggingface.co 上的模型存储库中托管的预训练模型的模型 ID。
  • local_files_only( bool ,可选,默认为 False ):是否只加载本地模型文件(即,不尝试下载模型)。
  • force_download (bool, 可选,默认为 False):是否强制重新下载模型权重和配置文件,覆盖缓存版本。
  • cache_dir( Union[str, os.PathLike] ,可选):用于缓存下载的预训练模型配置的目录路径。
    mirror (str, 可选):加速中国地区下载的镜像源,可填入镜像源地址

在这里插入图片描述
不出意外的话,果然就出现意外了,出现了超时的问题。

解决办法
(1) 网上自动下载超时,就直接在手动下载,进入hugging face官网的预训练模型, 然后可以在搜索栏查询需要下载的模型,比如笔者这里是 Qwen/Qwen2-7B-Instruct 模型
(2)通过HuggingFace模型ID自动下载,重新运行一次,因为有缓存,可能会快一些

在这里插入图片描述

进入hugging face官网搜索模型,下载所需模型到本地,看起来下面几个model差不多16G大小。

在这里插入图片描述

手动下载,下载好打包放一个文件夹下,然后就可以直接输入本地的模型路径,进行使用了。

在这里插入图片描述

D:.
    config.json
    generation_config.json
    gitattributes
    LICENSE
    merges.txt
    model-00001-of-00004.safetensors
    model-00002-of-00004.safetensors
    model-00003-of-00004.safetensors
    model-00004-of-00004.safetensors
    model.safetensors.index.json
    README.md
    tokenizer.json
    tokenizer_config.json
    vocab.json

如果直接重新运行后可能会出现新的报错,如下图所示:

解决方案是从本地加载模型,将之前下载好的文件,打包放在一个文件夹中,tokenizer
model路径均需要修改。
在这里插入图片描述
测试一下:
在这里插入图片描述

2.2 加载数据

import pandas as pd
dc = pd.read_csv('./dataset/en-zh.dic', sep='\t', header=None).set_index(0).to_dict()[1]

from tqdm import tqdm
lines = open('./dataset/test_en.txt').readlines()

2.3 撰写prompts并加入术语词典进行推理

result = []
for line in tqdm(lines):
    sp_words = [x for x in line.lower().split() if x in dc.keys()]
    sp_words_meaning = [dc[x] for x in sp_words]

    sp_prompt = '文章字符为:'
    if len(sp_words) > 0:
        for x, y in zip(sp_words, sp_words_meaning): 
            sp_prompt += f'{x} 翻译为 {y}; '
    # 主要任务
    messages = [
        {"role": "system", "content": "将英文翻译为中文,不要有其他输出,直接输出翻译后的文本。保留特殊单词的翻译。"},
    ]

    # 人工的词典的规则
    if len(sp_prompt) > 0:
        messages.append({"role": "user", "content": sp_prompt})
    messages.append({"role": "user", "content": f"待翻译文本(从英文翻译为中文):{line}"})
    
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )
    model_inputs = tokenizer([text], return_tensors="pt").to(device)
    
    generated_ids = model.generate(
        model_inputs.input_ids,
        max_new_tokens=512
    )
    generated_ids = [
        output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
    ]
    
    result_line = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
    result.append(result_line)
   

运行该段出现以下报错:
在这里插入图片描述
报错原因:Pytorch 运行时错误,预期所有张量位于同一设备上,但至少发现两个设备,cuda:0 和 cpu! 在恢复训练时
错误原因:这个错误通常是由于模型、输入张量或优化器的设备不一致引起的。Pytorch 中可以使用不同的设备(如GPU或CPU)进行计算,但在运行时,所有相关的张量应该在同一设备上。当我们在训练过程中切换设备或保存和加载模型时,就有可能出现这个错误。例如,在我们将模型从GPU中加载到CPU中进行测试或推理时,如果模型参数与输入张量的设备不一致,就会触发这个错误。
从网上找到以下3种解决办法:

方法一:明确指定设备
如果我们在代码中明确指定了设备,我们应该确保所有相关的张量都在同一设备上。我们可以使用 .to()方法将张量移动到指定设备上。例如,如果我们要将张量 tensor 移动到 GPU 上,可以使用 tensor =tensor.to("cuda")

方法二:自动将张量移动到所需设备
如果我们的代码没有明确指定设备,我们可以使用 torch. Device对象来自动将张量移动到所需设备。我们可以创建一个 device 对象,并在加载模型和处理输入数据时使用它。以下代码中,我们首先检查是否有可用的 GPU,然后根据结果创建一个 device 对象。接下来,我们将模型和输入张量移动到 device 对象所表示的设备上。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
tensor.to(device)

方法三:在加载模型时指定 map_location
当我们在加载模型时,可以使用 map_location参数来指定设备。map_location 接受一个字符串参数,用于将模型参数映射到指定设备。以下代码中,我们将加载的模型参数从 GPU(如果可用)映射到 CPU 上。

model = torch.load("model.pt", map_location="cuda")

测试后发现,当我统一把tensor和模型放进GPU后,RuntimeError: CUDA error: out of memorycuda就崩溃了
在这里插入图片描述
这时候我就意识到model不应该在一开始就放入cuda当中,回到梦开始的地方,让torch_dtypedevice_map改回auto

model = AutoModelForCausalLM.from_pretrained(
    "D:\Anaconda\envs\yolo\Lib\site-packages\Qwen2-7B-instruct",
    torch_dtype="auto",
    device_map="auto"
)

果不其然,跑通了,接下来就是大家自由发挥调参的过程了
在这里插入图片描述
最后导出结果文件qwen_submit.txt

with open('./results/qwen_submit.txt', 'w') as f:
    for line in result:
        line = line.strip().replace('\n', '')
        print(line)
        f.write(line + '\n')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值