一、简单介绍
要使用大模型来解决此机器翻译任务,要比自己训练一个任务简单许多,主要有两种解决方案:
- 直接调用大模型 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 memory
cuda就崩溃了
这时候我就意识到model
不应该在一开始就放入cuda当中,回到梦开始的地方,让torch_dtype
和device_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')