前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PaddleNLP 离线使用已下载好的社区模型

PaddleNLP 离线使用已下载好的社区模型

作者头像
AlphaHinex
发布2024-04-08 12:37:19
1010
发布2024-04-08 12:37:19
举报
文章被收录于专栏:周拱壹卒周拱壹卒

Part1TL;DR

使用 PaddleNLP 加载社区模型时,因为社区模型需联网下载,可先从在线环境进行模型下载,再将下载好的模型传输到离线环境中。此时在离线环境下可能会遇到 https://github.com/PaddlePaddle/PaddleNLP/pull/5817 中描述的问题,可参照该 PR files[1] 中内容修改,以支持离线环境的正常使用。

Part2PaddleNLP

PaddleNLP是一款简单易用且功能强大的自然语言处理开发库。聚合业界优质预训练模型并提供开箱即用的开发体验,覆盖NLP多场景的模型库搭配产业实践范例可满足开发者灵活定制的需求。—— https://github.com/PaddlePaddle/PaddleNLP

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

不过从实际使用下来的体验来看,文档内容对刚接触 PaddleNLP 的人并不友好,需要自行摸索和补充了解的内容较多。

PaddleNLP 依赖 PaddlePaddle[2]PaddlePaddle 分为 paddlepaddlepaddlepaddle-gpu 两个版本,想使用 GPU 进行计算,需要安装 paddlepaddle-gpu。使用 GPU 版本,还涉及到 显卡驱动[3]CUDA Toolkit[4]cuDNN[5]cuBLAS[6] 等,各个组件之间版本繁杂,兼容性问题较多,想构建起一个可用的环境不是一件容易的事情。

推荐使用 Docker 环境上手体验,安装 NVIDIA Container Toolkit[7] 之后,根据 CUDA 和 cuDNN 选择对应的镜像版本,如:

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

即便是官方提供的镜像,里面的组件版本也可能存在兼容性问题。上面 paddlecloud/paddlenlp:develop-gpu-cuda11.2-cudnn8-e72fb9 这个镜像,在引入 paddlenlp 中的 Taskflow 时,会抛出异常[8],需要在容器里把 paddlepaddle-gpu2.3.0 升级到 2.4.2

Part3Salesforce CodeGen

Salesforce CodeGen[9] 是一组开放的、支持多回合交谈式 AI 编程的大语言模型,包含多种尺寸和数据集,模型命名方式为:

codegen-{model-size}-{data}

model-size 有四个选项:350M2B6B,16B,代表每个模型的参数数量;data 有三个选项:nlmultimono

  • nl 模型基于 The Pile[10] —— 一个 825.18 GB 的英文语料库初始化和训练而来
  • multi 模型基于 nl 模型初始化,再使用由多种编程语言组成的代码语料库训练
  • mono 模型基于 multi 模型初始化,再使用 Python 代码语料库训练

关于各数据集的详细信息,可见 CodeGen: An Open Large Language Model for Code with Multi-Turn Program Synthesis[11]

Part4PaddleNLP 加载 CodeGen 模型

1Online

在线环境下,加载内置的模型时,会从预设的网址下载对应文件到本地。忽略了加载模型相关日志输出的,使用 CodeGen 模型通过提示词补全后续代码的示例代码如下:

代码语言:javascript
复制
$ 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']

此时在本地 ~/.paddlenlp 路径下,会下载好模型相关文件:

代码语言:javascript
复制
$ 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

2Offline

然而遗憾的是,上面的代码在离线环境无法直接使用,即使将模型相关文件全部传输到离线环境相同路径内,使用 Taskflow("code_generation", model="Salesforce/codegen-350M-mono") 时也会得到无法连接 bj.bcebos.com 域名的报错:

代码语言:javascript
复制
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'))

完整的报错信息可见 https://github.com/PaddlePaddle/PaddleNLP/pull/5817 。

报错原因

报相关错误的原因是,PaddleNLP 在加载社区模型(community/model-name)时,会先去判断对应模型文件在社区网站( 默认为:https://bj.bcebos.com/paddlenlp/models/community )是否存在,不论本地是否已经下载过了该模型。

解决思路

解决的思路很简单,在下载社区模型相关文件时,首先检查缓存路径中是否已经存在对应文件,如存在则直接使用,不存在再通过网络请求进行获取。

修改文件

可在错误堆栈中获取报错环境中需要修改的具体文件路径,如:

代码语言:javascript
复制
/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: 后面再添加一个 elif

代码语言:javascript
复制
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 后面增加一个 elif 条件:

代码语言:javascript
复制
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 部分调整:

代码语言:javascript
复制
         # 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):

效果验证

离线环境下可通过下列方式,验证加载已下载好的社区模型是否会报错:

代码语言:javascript
复制
from paddlenlp import Taskflow
codegen = Taskflow("code_generation", model="Salesforce/codegen-350M-mono",decode_strategy="greedy_search", repetition_penalty=1.0)
代码语言:javascript
复制
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)
代码语言:javascript
复制
from paddlenlp.transformers import AutoModel
AutoModel.from_pretrained("Salesforce/codegen-350M-mono")

全路径加载离线模型

在不修改代码的情况下,也可通过模型文件全路径在离线环境加载模型,但涉及到在线环境和离线环境的代码不一致,可自行取舍:

代码语言:javascript
复制
from paddlenlp.transformers import AutoModel
AutoModel.from_pretrained("~/.paddlenlp/models/Salesforce/codegen-350M-mono")
本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-05-13,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 周拱壹卒 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Part1TL;DR
  • Part2PaddleNLP
  • Part3Salesforce CodeGen
  • Part4PaddleNLP 加载 CodeGen 模型
    • 1Online
      • 2Offline
        • 报错原因
        • 解决思路
        • 修改文件
        • 效果验证
        • 全路径加载离线模型
    相关产品与服务
    NLP 服务
    NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com