日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

從零開始:Windows系統(tǒng)下Qwen2.5大模型的實踐教程(一)

 netouch 2025-02-13 發(fā)布于北京

本文將基于Windows系統(tǒng)和CPU環(huán)境,使用Qwen2.5系列模型,詳細實踐從大型語言模型的下載、部署到微調(diào)的全過程。

1、環(huán)境配置

1.1、部署開發(fā)環(huán)境

本地開發(fā)環(huán)境:windows

(1)python開發(fā)環(huán)境

pycharm 安裝pycharm(community版本):www.jetbrains.com/pycharm/dow…

anaconda 安裝anaconda:清華鏡像源,選擇合適的版本,例如:Anaconda3-2024.06-1-Windows-x86_64.exe 下載anaconda完成后,windows系統(tǒng)下點擊exe文件一路nex即可安裝完成。

③配置anaconda環(huán)境變量(非必須): 假設(shè)你的anaconda安裝地址為:D:\soft\anaconda;進入系統(tǒng)高級配置,添加系統(tǒng)變量:

在這里插入圖片描述

然后點擊Path,添加如下變量:

%ANACONDA_HOME% 
%ANACONDA_HOME%\Scripts 
%ANACONDA_HOME%\Library\mingw-w64\bin
%ANACONDA_HOME%\Library\usr\bin 
%ANACONDA_HOME%\Library\bin

配置完成后,使用conda --version可以看到anaconda已經(jīng)安裝完成:

在這里插入圖片描述

④anaconda使用:
一些簡單的命令,幫助我們使用它:

# 安裝一個新的anaconda環(huán)境,名為qwen1.5-4b,python版本為3.10
conda create -n qwen1.5-4b python=3.10
# 查詢安裝的anaconda環(huán)境
conda env list
# 手動切換anaconda環(huán)境
conda activate qwen1.5-4b
# 關(guān)閉anaconda環(huán)境
conda deactivate
# 檢查python的版本(當(dāng)前conda環(huán)境下的)
python --version

在我們新建完名為qianwen的conda虛擬環(huán)境后,去pycharm的setting->Python Interpreter中導(dǎo)入創(chuàng)建好的conda環(huán)境即可:

在這里插入圖片描述

1.2、大模型下載

huggingface:略

modelscape,魔搭社區(qū)提供了相應(yīng)的組件來供使用者下載:

# 安裝ModelScope
pip install modelscope
# 下載完整模型repo
modelscope download --model qwen/Qwen2.5-1.5B
# 下載單個文件(以README.md為例)
modelscope download --model qwen/Qwen2.5-1.5B README.md

示例如下:

我在base的conda環(huán)境下進行安裝相應(yīng)組件,然后調(diào)用modelscope命令進行下載,且該組件具備斷點續(xù)傳的功能,如果當(dāng)前網(wǎng)絡(luò)不佳,可以殺死命令行,重新執(zhí)行命令,已下載的文件內(nèi)容不會丟失,可以繼續(xù)在進度條附近開始下載任務(wù)。

在這里插入圖片描述

2、大模型部署使用

2.1、概述

使用:

import torch
from flask import Flask
from flask import request
from transformers import (AutoTokenizer, AutoModelForCausalLM, AutoModel,
                          Qwen2ForCausalLM, Qwen2Tokenizer)

# 參數(shù)
max_new_tokens: int = 512  # 生成響應(yīng)時最大的新token數(shù)
system_prompt = '你是一個專門分類新聞標(biāo)題的分析模型。你的任務(wù)是判斷給定新聞短文本標(biāo)題的分類。'
user_template_prompt = ('請評估以下網(wǎng)購評論的情感,不要返回0或1以外的任何信息,不要返回你的思考過程。'
                        '輸入正面評論輸出1,輸入負面評論輸出0。輸入如下:{}\n請?zhí)顚懩愕妮敵?)
eos_token_id = [151645, 151643]

app = Flask(__name__)
model_path = 'D:\project\llm\Qwen2.5-1.5B'
# tokenizer = AutoTokenizer.from_pretrained(model_path)
tokenizer = Qwen2Tokenizer.from_pretrained(model_path)
# model = AutoModelForCausalLM.from_pretrained(model_path, device_map='cpu').eval()
model = Qwen2ForCausalLM.from_pretrained(model_path, device_map='cpu').eval()

# 非流式請求
@app.route('/chat', methods=['POST'])
def chat():
    # 系統(tǒng)設(shè)定和prompt
    req_json = request.json
    content = user_template_prompt.format(req_json['message'])
    messages = [
        {'role': 'system', 'content': system_prompt},
        {'role': 'user', 'content': content}
    ]
    print('input: ' + content)
    input_ids = tokenizer.apply_chat_template(messages,
                                              tokenize=False,
                                              add_generation_prompt=True)
    inputs = tokenizer([input_ids], return_tensors='pt').to(model.device)
    generated_ids = model.generate(
        inputs.input_ids,
        max_new_tokens=max_new_tokens,
        eos_token_id=eos_token_id,  # 結(jié)束令牌,模型生成這個token時,停止生成
    )
    generated_ids = [
        output_ids[len(inputs):] for inputs, output_ids in zip(inputs.input_ids, generated_ids)
    ]
    print(f'generated_ids=\n{generated_ids}')
    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
    print(response)
    # 使用占位符拼接字符串
    return response

if __name__ == '__main__':
    app.run(port=8080, host='0.0.0.0')

其中用到的Qwen2ForCausalLM替換了AutoModelForCausalLM,是一個基于Transformer結(jié)構(gòu)的decoder-only模型,它是Qwen大模型的第二代架構(gòu)。

2.2、參數(shù)

通常來說參數(shù)越大的大模型。其中需要關(guān)注到的一些問題以及使用上需要注意的地方:

①apply_chat_template

用在會話中,告訴大模型接下來應(yīng)該生成新的東西,并且包含了整個會話的上下文信息。使用如下:

input_ids = tokenizer.apply_chat_template(messages,  # 輸入的純文本信息
                                          tokenize=False,  # 告訴大模型暫時不需要分詞
                                          add_generation_prompt=True)  # 添加一個特殊的標(biāo)記,告訴大模型接下來應(yīng)該生成新的文本內(nèi)容。

輸出如下:

在這里插入圖片描述

'<|im_start|>system
你是一個專門評估網(wǎng)購評論情感的分析模型。你的任務(wù)是判斷給定評論是正面還是負面。<|im_end|>
<|im_start|>user
請評估以下網(wǎng)購評論的情感,不要返回0或1以外的任何信息,不要返回你的思考過程。如果是正面評論返回1,如果是負面評論返回0:不錯!挺合適<|im_end|>
<|im_start|>assistant
'

②eos_token_id

設(shè)定了大模型生成文本的分割符,其中eos_token_id = [151645, 151643],兩個id的含義分別是:

tokenizer.convert_ids_to_tokens(151645)    # <|im_end|>
tokenizer.convert_ids_to_tokens(151643)    # <|endoftext|>
tokenizer.convert_ids_to_tokens(1773)      # 。

這兩個標(biāo)記與輸入中的標(biāo)記保持一致。若不設(shè)置該值,在未達到最大返回token數(shù)之前,對話將不會自動終止,大模型可能會進行不必要的自問自答。

在這里插入圖片描述

為了控制大模型可能產(chǎn)生的不穩(wěn)定輸出,設(shè)置停用詞是一種有效手段。除了使用 eos_token_id 外,還可以采用以下方法:

generation_config = GenerationConfig(use_cache=True,
                                     repetition_penalty=repetition_penalty,
                                     do_sample=False,  # 取消采樣,使用貪心策略,輸出是確定的
                                     stop_strings='}')
generated_ids = model.generate(input_ids,
                               tokenizer=tokenizer,
                               generation_config=generation_config)
                                     

對于模型的推理參數(shù),可以統(tǒng)一放置在 GenerationConfig 中。通過 stop_strings 參數(shù)(其值可為字符串或字符串列表)來設(shè)置停用詞。在上例中,將 } 設(shè)為停用詞,這在要求大模型返回JSON數(shù)據(jù)時尤為有效,能夠有效避免大模型在輸出完整JSON數(shù)據(jù)后繼續(xù)進行不必要的推理。

③repetition_penalty

使用如下:

repetition_penalty float = 1.2  # 用于懲罰重復(fù)生成相同token的參數(shù)
generated_ids = model.generate(
    inputs.input_ids,
    max_new_tokens=max_new_tokens,
    repetition_penalty=repetition_penalty,  # 解決問題后面有過多重復(fù)問答
)

某些時候,大模型也會持續(xù)重復(fù)之前的對話,直到生成的token數(shù)等于max_new_tokens為止。情況如下:

在這里插入圖片描述

這個值不宜過低或過高:過低不生效;過高會導(dǎo)致大模型不敢生成正確答案,因為輸入的prompt中攜帶了正確答案。目前看1.2是一個比較合適的值。

④skip_special_tokens=True

這個告訴分詞器在解碼時跳過任何特殊的標(biāo)記,如結(jié)束標(biāo)記end-of-sequence token或其他模型特定的標(biāo)記。

由于我們在上面調(diào)用model時設(shè)置了停用詞,在大模型推理到停用詞就會返回輸出。如果不設(shè)置該參數(shù),則效果如下:

1<|endoftext|>

優(yōu)化參數(shù)之后,效果如下:

gpt-4oqwen2.5-1.5bqwen2.5-1.5b_修改后qwen2.5-1.5b_微調(diào)后qwen2.5-3bqwen2.5-3b_修改后
二元分類0.96幾乎無法輸出規(guī)定格式的結(jié)果0.93<暫未微調(diào)>0.620.91
多元分類樣本100條0.930.670.90.120.72
樣本1000條0.7850.5790.796

2.3、總結(jié)

  1. 本章節(jié)主要關(guān)注qwen2.5-1.5b_修改后的結(jié)果,有兩個主要成果:
    1.1、修改了上述等啟動參數(shù)之后,大模型能夠正常輸出預(yù)期的結(jié)果
    1.2、對于相對簡單的人呢?zé)o

  2. 下一章節(jié)將進行qwen2.5-1.5b模型的微調(diào)

2.3.1、最終代碼

最終代碼如下:

import torch
from flask import Flask
from flask import request
from transformers import (AutoTokenizer, AutoModelForCausalLM, AutoModel,
                          Qwen2ForCausalLM, Qwen2Tokenizer)
from peft import PeftModel

# 參數(shù)
max_new_tokens: int = 64  # 生成響應(yīng)時最大的新token數(shù)
temperature: float = 0.6  # 控制生成文本的隨機性
top_p: float = 0.9  # 用于概率限制的參數(shù),有助于控制生成文本的多樣性
top_k: int = 32  # 控制生成過程中每一步考慮的最可能token的數(shù)量
repetition_penalty: float = 1.2  # 用于懲罰重復(fù)生成相同token的參數(shù)
system_template_prompt = '你是一個專門評估網(wǎng)購評論情感的分析模型。你的任務(wù)是判斷給定評論是正面還是負面。'
system_prompt = '你是一個專門分類新聞標(biāo)題的分析模型。你的任務(wù)是判斷給定新聞短文本標(biāo)題的分類。'
user_template_prompt = ('請評估以下評論,不要返回0或1以外的任何信息,不要返回你的思考過程。'
                        '如果是正面評論輸出1,是反面評論輸出0。輸入如下:{}\n請?zhí)顚懩愕妮敵觯?)
user_prompt = ('請將以下新聞短文本標(biāo)題分類到以下類別之一:故事、文化、娛樂、體育、財經(jīng)、房產(chǎn)、汽車、教育、'
               '科技、軍事、旅游、國際、股票、農(nóng)業(yè)、游戲。輸入如下:\n{}\n請?zhí)顚懩愕妮敵觯?)
eos_token_id = [151645, 151643]

app = Flask(__name__)
lora_model_path = './output/Qwen2.5-1.5b/checkpoint-100'
model_path = 'D:\project\llm\Qwen2.5-1.5B'
# 從指定路徑加載大模型的分詞器(tokenizer),用于加載預(yù)訓(xùn)練的文本處理模型(Tokenizer),以便將文本數(shù)據(jù)轉(zhuǎn)換為模型可以接受的輸入格式。
tokenizer = Qwen2Tokenizer.from_pretrained(model_path)
# AutoModelForCausalLM更適合語言大模型
model = Qwen2ForCausalLM.from_pretrained(model_path, device_map='cpu').eval()

# 非流式請求
@app.route('/chat_old', methods=['POST'])
def chat_old():
    # 系統(tǒng)設(shè)定和prompt
    req_json = request.json
    content = user_template_prompt.format(req_json['message'])
    messages = [
        {'role': 'system', 'content': system_template_prompt},
        {'role': 'user', 'content': content}
    ]
    # 使用tokenizer將整個會話轉(zhuǎn)換成模型可以理解的input_ids,并將這些input_ids輸入到模型
    # tokenize=False 表示不要立即分詞,只是使用apply_chat_template將會話進行格式化
    input_ids = tokenizer.apply_chat_template(messages,
                                              tokenize=False,
                                              add_generation_prompt=True)
    print(f'input:{input_ids}')
    inputs = tokenizer([input_ids], return_tensors='pt').to(model.device)
    generated_ids = model.generate(
        inputs.input_ids,
        max_new_tokens=max_new_tokens,
        repetition_penalty=repetition_penalty,  # 解決問題后面有過多重復(fù)問答(對重復(fù)token的懲罰)
        eos_token_id=eos_token_id,  # 結(jié)束令牌,模型生成這個token時,停止生成
    )
    generated_ids = [
        output_ids[len(inputs):] for inputs, output_ids in zip(inputs.input_ids, generated_ids)
    ]
    print(f'generated_ids=\n{generated_ids}')
    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
    response = response.encode('utf-8', errors='ignore').decode('utf-8')
    print(response)
    # 使用占位符拼接字符串
    return response

@app.route('/chat', methods=['POST'])
def chat():
    # 系統(tǒng)設(shè)定和prompt
    req_json = request.json
    prompt = user_prompt.format(req_json['message'])
    print(prompt)
    # 非會話的輸入方式,將單句話進行分詞成token ids
    inputs = tokenizer(prompt, return_tensors='pt')
    input_ids = inputs.input_ids

    # Generate
    generate_ids = model.generate(input_ids=input_ids,
                                  bos_token_id=151645,  # 開始令牌(在生成文本時,模型會在輸入序列的末尾添加這個令牌,以指示新生成的文本的開始。)
                                  max_new_tokens=len(input_ids) + 1,
                                  repetition_penalty=repetition_penalty)
    print(generate_ids)
    response = tokenizer.batch_decode(generate_ids, skip_special_tokens=True)[0]
    print(response)
    # # 去掉response中的包含prompt的文本
    response = response[len(prompt):]
    return response.strip()
    

if __name__ == '__main__':
    app.run(port=8080, host='0.0.0.0')

2.3.2、數(shù)據(jù)集

數(shù)據(jù)集如下:

二元分類數(shù)據(jù)集:電商平臺評論數(shù)據(jù)集

多元分類數(shù)據(jù)集:今日頭條文本分類數(shù)據(jù)集 / 數(shù)據(jù)集 / HyperAI超神經(jīng)

其他:天池數(shù)據(jù)集、ChineseNlpCorpus

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多