PaddleNLP 離線使用已下載好的社區(qū)模型

cover

原文地址:https://alphahinex.github.io/2023/05/14/paddlenlp-offline-use-community-model/


description: "修改源碼,或者修改模型名稱(chēng)為全路徑"
date: 2023.05.14 10:26
categories:
- AI
tags: [AI, PaddleNLP]
keywords: PaddlePaddle, PaddleNLP, NVIDIA, Salesforce CodeGen, GPU, offline


TL;DR

使用 PaddleNLP 加載社區(qū)模型時(shí),因?yàn)樯鐓^(qū)模型需聯(lián)網(wǎng)下載蝇刀,可先從在線環(huán)境進(jìn)行模型下載凭语,再將下載好的模型傳輸?shù)诫x線環(huán)境中蜒车。此時(shí)在離線環(huán)境下可能會(huì)遇到 https://github.com/PaddlePaddle/PaddleNLP/pull/5817 中描述的問(wèn)題潭袱,可參照該 PR files 中內(nèi)容修改摇零,以支持離線環(huán)境的正常使用磨确。

PaddleNLP

PaddleNLP是一款簡(jiǎn)單易用且功能強(qiáng)大的自然語(yǔ)言處理開(kāi)發(fā)庫(kù)沽甥。聚合業(yè)界優(yōu)質(zhì)預(yù)訓(xùn)練模型并提供開(kāi)箱即用的開(kāi)發(fā)體驗(yàn),覆蓋NLP多場(chǎng)景的模型庫(kù)搭配產(chǎn)業(yè)實(shí)踐范例可滿足開(kāi)發(fā)者靈活定制的需求乏奥。 —— https://github.com/PaddlePaddle/PaddleNLP

PaddleNLP 文檔地址:https://paddlenlp.readthedocs.io/zh/latest/index.html#

不過(guò)從實(shí)際使用下來(lái)的體驗(yàn)來(lái)看摆舟,文檔內(nèi)容對(duì)剛接觸 PaddleNLP 的人并不友好,需要自行摸索和補(bǔ)充了解的內(nèi)容較多邓了。

PaddleNLP 依賴 PaddlePaddle恨诱,PaddlePaddle 分為 paddlepaddlepaddlepaddle-gpu 兩個(gè)版本,想使用 GPU 進(jìn)行計(jì)算骗炉,需要安裝 paddlepaddle-gpu照宝。使用 GPU 版本,還涉及到 顯卡驅(qū)動(dòng)句葵、CUDA Toolkit厕鹃、cuDNNcuBLAS 等剂碴,各個(gè)組件之間版本繁雜把将,兼容性問(wèn)題較多,想構(gòu)建起一個(gè)可用的環(huán)境不是一件容易的事情忆矛。

推薦使用 Docker 環(huán)境上手體驗(yàn)察蹲,安裝 NVIDIA Container Toolkit 之后,根據(jù) CUDA 和 cuDNN 選擇對(duì)應(yīng)的鏡像版本洪碳,如:

docker run --name dev --runtime=nvidia -v $PWD:/mnt -p 8888:8888 -it paddlecloud/paddlenlp:develop-gpu-cuda11.2-cudnn8-e72fb9 /bin/bash

即便是官方提供的鏡像递览,里面的組件版本也可能存在兼容性問(wèn)題。上面 paddlecloud/paddlenlp:develop-gpu-cuda11.2-cudnn8-e72fb9 這個(gè)鏡像瞳腌,在引入 paddlenlp 中的 Taskflow 時(shí)绞铃,會(huì)拋出異常,需要在容器里把 paddlepaddle-gpu2.3.0 升級(jí)到 2.4.2嫂侍。

Salesforce CodeGen

Salesforce CodeGen 是一組開(kāi)放的儿捧、支持多回合交談式 AI 編程的大語(yǔ)言模型,包含多種尺寸和數(shù)據(jù)集挑宠,模型命名方式為:

codegen-{model-size}-{data}

model-size 有四個(gè)選項(xiàng):350M菲盾、2B6B,16B各淀,代表每個(gè)模型的參數(shù)數(shù)量懒鉴;data 有三個(gè)選項(xiàng):nlmulti碎浇、mono临谱。

  • nl 模型基于 The Pile —— 一個(gè) 825.18 GB 的英文語(yǔ)料庫(kù)初始化和訓(xùn)練而來(lái)
  • multi 模型基于 nl 模型初始化,再使用由多種編程語(yǔ)言組成的代碼語(yǔ)料庫(kù)訓(xùn)練
  • mono 模型基于 multi 模型初始化奴璃,再使用 Python 代碼語(yǔ)料庫(kù)訓(xùn)練

關(guān)于各數(shù)據(jù)集的詳細(xì)信息悉默,可見(jiàn) CodeGen: An Open Large Language Model for Code with Multi-Turn Program Synthesis

PaddleNLP 加載 CodeGen 模型

Online

在線環(huán)境下苟穆,加載內(nèi)置的模型時(shí)抄课,會(huì)從預(yù)設(shè)的網(wǎng)址下載對(duì)應(yīng)文件到本地。忽略了加載模型相關(guān)日志輸出的雳旅,使用 CodeGen 模型通過(guò)提示詞補(bǔ)全后續(xù)代碼的示例代碼如下:

$ python3
>>> from paddlenlp import Taskflow
>>> codegen = Taskflow("code_generation", model="Salesforce/codegen-350M-mono",decode_strategy="greedy_search", repetition_penalty=1.0)
>>> print(codegen("def lengthOfLongestSubstring(self, s: str) -> int:"))
['\n        if not s:\n            return 0\n        \n        dic = {}\n        max_len = 0\n        \n        for i in range(len(s)):\n         if s[i] in dic:\n                dic[s[i]] += 1\n                if dic[s[i]] > max_len:\n                    max_len = dic[s[i]]\n            else:\n                dic[s[i]] = 1\n        \n        return max_len']

此時(shí)在本地 ~/.paddlenlp 路徑下跟磨,會(huì)下載好模型相關(guān)文件:

$ pwd
/root/.paddlenlp
$ tree
.
├── datasets
├── models
│   ├── Salesforce
│   │   └── codegen-350M-mono
│   │       ├── added_tokens.json
│   │       ├── config.json
│   │       ├── merges.txt
│   │       ├── model_config.json
│   │       ├── model_state.pdparams
│   │       ├── special_tokens_map.json
│   │       ├── tokenizer_config.json
│   │       └── vocab.json
│   └── embeddings
└── packages

Offline

然而遺憾的是,上面的代碼在離線環(huán)境無(wú)法直接使用攒盈,即使將模型相關(guān)文件全部傳輸?shù)诫x線環(huán)境相同路徑內(nèi)抵拘,使用 Taskflow("code_generation", model="Salesforce/codegen-350M-mono") 時(shí)也會(huì)得到無(wú)法連接 bj.bcebos.com 域名的報(bào)錯(cuò):

HTTPSConnectionPool(host='bj.bcebos.com', port=443): Max retries exceeded with url: /paddlenlp/models/community/Salesforce/codegen-350M-mono/config.json (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x140053a90>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))

完整的報(bào)錯(cuò)信息可見(jiàn) https://github.com/PaddlePaddle/PaddleNLP/pull/5817

報(bào)錯(cuò)原因

報(bào)相關(guān)錯(cuò)誤的原因是沦童,PaddleNLP 在加載社區(qū)模型(community/model-name)時(shí)仑濒,會(huì)先去判斷對(duì)應(yīng)模型文件在社區(qū)網(wǎng)站( 默認(rèn)為:https://bj.bcebos.com/paddlenlp/models/community )是否存在,不論本地是否已經(jīng)下載過(guò)了該模型偷遗。

解決思路

解決的思路很簡(jiǎn)單墩瞳,在下載社區(qū)模型相關(guān)文件時(shí),首先檢查緩存路徑中是否已經(jīng)存在對(duì)應(yīng)文件氏豌,如存在則直接使用喉酌,不存在再通過(guò)網(wǎng)絡(luò)請(qǐng)求進(jìn)行獲取。

修改文件

可在錯(cuò)誤堆棧中獲取報(bào)錯(cuò)環(huán)境中需要修改的具體文件路徑泵喘,如:

/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/paddlenlp/transformers/model_utils.py

需要修改的文件如下泪电,或參考 https://github.com/PaddlePaddle/PaddleNLP/pull/5817/files

  • paddlenlp/transformers/configuration_utils.py

_get_config_dict 方法 elif from_hf_hub: 后面再添加一個(gè) elif

elif os.path.isfile(os.path.join(cache_dir, CONFIG_NAME)):
    resolved_config_file = os.path.join(cache_dir, CONFIG_NAME)
  • paddlenlp/transformers/model_utils.py

_resolve_model_file_path 方法 0. when it is local file 后面增加一個(gè) elif 條件:

elif os.path.isfile(os.path.join(cache_dir, cls.resource_files_names["model_state"])):
    return os.path.join(cache_dir, cls.resource_files_names["model_state"])
  • paddlenlp/transformers/auto/modeling.py

_from_pretrained 方法 # Assuming from community-contributed pretrained models 部分調(diào)整:

         # Assuming from community-contributed pretrained models
         else:
+            cached_standard_config = os.path.join(cache_dir, cls.model_config_file)
+            cached_legacy_config = os.path.join(cache_dir, cls.legacy_model_config_file)
             standard_community_url = "/".join(
                 [COMMUNITY_MODEL_PREFIX, pretrained_model_name_or_path, cls.model_config_file]
             )
             legacy_community_url = "/".join(
                 [COMMUNITY_MODEL_PREFIX, pretrained_model_name_or_path, cls.legacy_model_config_file]
             )
             try:
-                if url_file_exists(standard_community_url):
+                if os.path.isfile(cached_standard_config):
+                    resolved_vocab_file = cached_standard_config
+                elif url_file_exists(standard_community_url):
                     resolved_vocab_file = get_path_from_url_with_filelock(standard_community_url, cache_dir)
+                elif os.path.isfile(cached_legacy_config):
+                    resolved_vocab_file = cached_legacy_config
                 elif url_file_exists(legacy_community_url):

效果驗(yàn)證

離線環(huán)境下可通過(guò)下列方式纪铺,驗(yàn)證加載已下載好的社區(qū)模型是否會(huì)報(bào)錯(cuò):

from paddlenlp import Taskflow
codegen = Taskflow("code_generation", model="Salesforce/codegen-350M-mono",decode_strategy="greedy_search", repetition_penalty=1.0)
from paddlenlp.transformers import CodeGenForCausalLM, CodeGenTokenizer
CodeGenTokenizer.from_pretrained("Salesforce/codegen-350M-mono")
CodeGenForCausalLM.from_pretrained("Salesforce/codegen-350M-mono", load_state_as_np=True)
from paddlenlp.transformers import AutoModel
AutoModel.from_pretrained("Salesforce/codegen-350M-mono")

全路徑加載離線模型

在不修改代碼的情況下相速,也可通過(guò)模型文件全路徑在離線環(huán)境加載模型,但涉及到在線環(huán)境和離線環(huán)境的代碼不一致鲜锚,可自行取舍:

from paddlenlp.transformers import AutoModel
AutoModel.from_pretrained("~/.paddlenlp/models/Salesforce/codegen-350M-mono")
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末突诬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芜繁,更是在濱河造成了極大的恐慌旺隙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骏令,死亡現(xiàn)場(chǎng)離奇詭異蔬捷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)榔袋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)周拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人摘昌,你說(shuō)我怎么就攤上這事速妖。” “怎么了聪黎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵罕容,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我稿饰,道長(zhǎng)锦秒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任喉镰,我火速辦了婚禮旅择,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侣姆。我一直安慰自己生真,他們只是感情好沉噩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著柱蟀,像睡著了一般川蒙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上长已,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天畜眨,我揣著相機(jī)與錄音,去河邊找鬼术瓮。 笑死康聂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胞四。 我是一名探鬼主播恬汁,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼辜伟!你這毒婦竟也來(lái)了蕊连?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤游昼,失蹤者是張志新(化名)和其女友劉穎甘苍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體烘豌,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡载庭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了廊佩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囚聚。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖标锄,靈堂內(nèi)的尸體忽然破棺而出顽铸,到底是詐尸還是另有隱情,我是刑警寧澤料皇,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布谓松,位于F島的核電站,受9級(jí)特大地震影響践剂,放射性物質(zhì)發(fā)生泄漏鬼譬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一逊脯、第九天 我趴在偏房一處隱蔽的房頂上張望优质。 院中可真熱鬧,春花似錦、人聲如沸巩螃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)避乏。三九已至颤枪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淑际,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工扇住, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留春缕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓艘蹋,卻偏偏與公主長(zhǎng)得像锄贼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子女阀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容