通义千问本地部署教程 Qwen-1.5-1.8B/7B/14B Windows-详细认真版

通义千问本地部署教程🚀

        本专栏的第四弹,在实现了联网调用通义千问模型进行多轮对话,流式输出,以及结合LangChain实现自建知识库之后,开始准备考虑实现对大模型进行本地部署,网上找不到看着比较舒服的教程,本文对于部署大模型过程中比较重要的,环境搭建,模型下载等进行详细介绍,如果您没有研究需求只有使用需求,请直接安装环境-下载模型-运行代码,由于这部分内容实在太多,所以可能还是需要一些相关的基础才能完全读懂本篇文字,如果您之前稍微研究过大语言模型的本地部署我相信这篇文章一定能解决您的问题,如果有什么我写的不清楚的地方,非常欢迎各位给我留言评论探讨,然后虽然我看好像其他相关的文章好像都收费,但是我还是决定免费,由于我是会员所以我有版权保护,所以不用太担心别人直接爬走,希望帮助到各位,如果可以您点个赞我会非常开心的。

2024年2月26号该文章第一次发布,2024年7月24号被魔搭官方社区收录,感谢认可!


系列文章:
1.调用阿里通义千问大语言模型API-小白新手教程-python
2.LangChain结合通义千问的自建知识库
3.使用LangChain结合通义千问API基于自建知识库的多轮对话和流式输出
4.解决LangChain构建知识向量库的过程中官方API无法自定义文本切割方式的问题-例如按行切分
5.通义千问本地部署教程Qwen-7B-Chat Qwen1.5-1.8B Windows-详细认真版

1.Qwen-7B-Chat 模型的下载


        首先需要下载通义千问的Qwen-7B-Chat的模型文件,其下载地址为阿里官方的大语言模型社区,魔搭ModelScope,其中通义千问的Qwen-7B-Chat 的下载和相关介绍的地址为。
https://modelscope.cn/models/qwen/Qwen-7B-Chat/summary
在这里插入图片描述
点击其中的模型文件,进入模型文件页面,之后点击右侧的下载模型
在这里插入图片描述
        右侧会出现两个下载方式,第一个是用SDK也就是安装安装工具包下载,第二个是用git下载,这里还是推荐用第一种,但是实际使用的时候,还需要添加一个新的参数用来设置下载地址,否则就会下载到安装包的目录下
在这里插入图片描述

        在安装好环境之后,之后运行下面的代码就可以下载到本地了,模型大小一共是14.4个Gcache_dir就是自己设置的模型下载的地址是是一个文件夹的目录

from modelscope import snapshot_download
model_dir = snapshot_download('qwen/Qwen-7B-Chat',cache_dir='自己的地址')

        运行起来的效果如下,当运行到下载1个G以上的文件的时候会卡住一阵,才会开始下载,如果这里长时间没响应那就是网络条件不行了。
在这里插入图片描述

2.Qwen-7B-Chat 环境的安装


        为了运行之后本地部署的Qwen-7B-Chat模型,我们需要根据要求在Anaconda中安装一个满足模型运行要求的虚拟环境,其官方的配置环境要求如下,本文配置的环境为使用GPU Pytorch的版本。官网的要求如下。
在这里插入图片描述

        除了常规的Pytorch之外还需要进行以下两次安装

  1. 安装modelscope可以用来下载模型,在下载的过程中有网络要求我用的宽带为100M的网线链接最后下了不到1个小时,如果网络不行在下载到大文件的时候会断开链接。
pip install modelscope
  1. 然后是官方说的运行Qwen-7B-需要安装的依赖。
    在这里插入图片描述
pip install transformers==4.32.0 accelerate tiktoken einops scipy transformers_stream_generator==0.0.4 peft deepspeed

        具体安装过程根据不同的系统电脑各有各的微小差异,而且有时候充满了玄学,在这里我说一下我自己的配置,然后给大家参考。

名称硬件型号/软件版本
CPU英特尔 Core i7-14700KF
GPUNVIDIA GeForce RTX 4070 Ti(12 GB/华硕)
CUDADriver Version: 546.65 CUDA Version: 12.3
内存32 GB(威刚 DDR5 6000MHz16GB x2)
硬盘GAMMIX S70 SE(1024 GB/固态硬盘)
Python3.9.15
Numpy1.23.4
pip22.3.1
Torch1.13.1
modelscope1.12.0

3.运行本地的部署代码实现多轮对话


        在安装好环境以及下载了模型文件之后,就可以运行官方的例程代码来观察对话效果,官方的快速开始代码如下,先给出官方代码之后我会精简然后介绍重要参数的作用

from modelscope import AutoModelForCausalLM, AutoTokenizer
from modelscope import GenerationConfig

# Note: The default behavior now has injection attack prevention off.
tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-7B-Chat", trust_remote_code=True)

# use bf16
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, bf16=True).eval()
# use fp16
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, fp16=True).eval()
# use cpu only
# model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="cpu", trust_remote_code=True).eval()
# use auto mode, automatically select precision based on the device.
model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True).eval()

# Specify hyperparameters for generation. But if you use transformers>=4.32.0, there is no need to do this.
# model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True) # 可指定不同的生成长度、top_p等相关超参

# 第一轮对话 1st dialogue turn
response, history = model.chat(tokenizer, "你好", history=None)
print(response)
# 你好!很高兴为你提供帮助。

# 第二轮对话 2nd dialogue turn
response, history = model.chat(tokenizer, "给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history)
print(response)
# 这是一个关于一个年轻人奋斗创业最终取得成功的故事。
# 故事的主人公叫李明,他来自一个普通的家庭,父母都是普通的工人。从小,李明就立下了一个目标:要成为一名成功的企业家。
# 为了实现这个目标,李明勤奋学习,考上了大学。在大学期间,他积极参加各种创业比赛,获得了不少奖项。他还利用课余时间去实习,积累了宝贵的经验。
# 毕业后,李明决定开始自己的创业之路。他开始寻找投资机会,但多次都被拒绝了。然而,他并没有放弃。他继续努力,不断改进自己的创业计划,并寻找新的投资机会。
# 最终,李明成功地获得了一笔投资,开始了自己的创业之路。他成立了一家科技公司,专注于开发新型软件。在他的领导下,公司迅速发展起来,成为了一家成功的科技企业。
# 李明的成功并不是偶然的。他勤奋、坚韧、勇于冒险,不断学习和改进自己。他的成功也证明了,只要努力奋斗,任何人都有可能取得成功。

# 第三轮对话 3rd dialogue turn
response, history = model.chat(tokenizer, "给这个故事起一个标题", history=history)
print(response)
# 《奋斗创业:一个年轻人的成功之路》

        运行的结果如下,红色的是各种前置检查信息,我专门断网测试了一下输出的也是这些内容。

在这里插入图片描述

        之后对代码进行精简,实现一个简单的多轮对话功能。精简之后的代码如下。其中的device_map如果设置为cpu则模型将会在cpu上运行,如果设置为Auto如果Pytorch为GPU版本的话将会在GPU上运行。关于非常容易关注到的tokenizer,官方是这吗说的🤭说现在还没有概念的对应,所以无需纠结这块是啥东西。根据经验推测它应该是跟分词有关的一个东西。

在这里插入图片描述

from modelscope import AutoModelForCausalLM, AutoTokenizer

model_path = "D:\qwen\Qwen-7B-Chat"

tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", trust_remote_code=True).eval()

history=None

while True:
    message = input('User:')
    response, history = model.chat(tokenizer, message, history=history)
    print('System:',end='')
    print(response)
  1. from modelscope import AutoModelForCausalLM, AutoTokenizer: 从modelscope库中导入两个类:AutoModelForCausalLMAutoTokenizer

  2. model_path = "D:\qwen\Qwen-7B-Chat": 定义模型文件存放的路径。这里假定你已经有了一个预训练模型,存储在指定的路径下。

  3. tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True): 从给定的路径加载预训练的分词器。trust_remote_code=True参数允许加载并执行远程代码,这对于加载自定义的分词器逻辑可能是必需的。

  4. model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", trust_remote_code=True).eval(): 类似地,从指定路径加载预训练的语言模型,并将模型设置为评估模式。device_map="auto"指示库自动选择运行模型的设备(CPU或GPU).eval()方法用于切换到模型的评估模式,这通常在预测时使用。

  5. history=None: 初始化history变量。这个变量用于存储对话历史,使模型能够在生成回答时考虑到之前的上下文。

  6. while True:: 开始一个无限循环,用于持续接收用户输入并生成回应。

  7. message = input('User:'): 通过input函数接收用户的输入。

  8. response, history = model.chat(tokenizer, message, history=history): 调用模型的chat方法生成回应。这个方法接受分词器、用户的消息以及可选的历史记录作为输入,并返回模型的回应和更新后的历史记录。更新后的历史记录可以在下一次迭代中使用,以便模型能够参考之前的对话内容。

  9. print('System:',end='')print(response): 首先打印System:,不换行,然后打印模型生成的回应。

        运行结果如下:

在这里插入图片描述

        本设备在模型推理时的性能检测效果如下。

在这里插入图片描述

        由于其生成的比较慢,我就加了一下每次推理运行的时间,其运行时间效果如图,我大概估计了一下,输出一个Token的推理时间大概为1S,在官方的快速开始的例程序中,所以等待的过程非常的难受。

在这里插入图片描述

4.结合Swift库实现流式输出-认真总结


        在经历了非常不舒服的等待之后,决定尝试一下流式输出,然后这部分代码就非常的不好找了,我在进入了ModelScope的官方咨询群之后询问了半天,加上自己参悟最终实现了在Windows上使用本地部署的通义千问模型多轮对话的效果,那接下来直接开始。我会把这个过程以及采的坑详细说明,如果您是有相关基础的想直接使用的技术人员直接跳到最后的代码部分即可

4.1 该部分实现过程和踩坑经验分享

        首先,对于流式输出官方人员给我发的一个链接是这样的。

在这里插入图片描述

        点开里面的推理文档,下滑找到对应的代码。
链接为Swift官方推理文档

在这里插入图片描述

        这里我直接把代码复制到下面,我们先不纠结里面的内容,这里用到了一个新的库swift,首先需要安装它,这里是一个坑
其安装命令为:

pip install ms-swift

        而并不是pip install swift,如果你用的是pip install swift安装会安装不上,会出现如下错误,提示你要取下载红帽和Ubtuntu版本的库,但是这是Liunx系统的库,所以安装不上,只有运行pip install ms-swift才能安装成功。

在这里插入图片描述

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'

from swift.llm import (
    get_model_tokenizer, get_template, inference_stream, ModelType, get_default_template_type,
)
from swift.utils import seed_everything

model_type = ModelType.qwen_7b_chat
template_type = get_default_template_type(model_type)
print(f'template_type: {template_type}')  # template_type: qwen

model, tokenizer = get_model_tokenizer(model_type, model_kwargs={'device_map': 'auto'})

template = get_template(template_type, tokenizer)
seed_everything(42)
query = '浙江的省会在哪里?'
gen = inference_stream(model, template, query)
print(f'query: {query}')
for response, history in gen:
    print(f'response: {response}')
query = '这有什么好吃的?'
gen = inference_stream(model, template, query, history)
print(f'query: {query}')
for response, history in gen:
    print(f'response: {response}')
print(f'history: {history}')

"""Out[0]
query: 浙江的省会在哪里?
...
response: 浙江省的省会是杭州。
query: 这有什么好吃的?
...
response: 杭州市有很多著名的美食,例如西湖醋鱼、龙井虾仁、糖醋排骨、毛血旺等。此外,还有杭州特色的点心,如桂花糕、荷花酥、艾窝窝等。
history: [('浙江的省会在哪里?', '浙江省的省会是杭州。'), ('这有什么好吃的?', '杭州市有很多著名的美食,例如西湖醋鱼、龙井虾仁、糖醋排骨、毛血旺等。此外,还有杭州特色的点心,如桂花糕、荷花酥、艾窝窝等。')]
"""

        直接说这个代码的结论,首先这个代码是下载和推理一体的代码,当第一次运行的时候,会在指定路径下下载模型文件,第二次运行时检测到指定文件夹下的文件了之后,就会开始进入模型推理阶段,下面的运行输出是我的模型第二次之后运行的结果。

在这里插入图片描述

        第二次运行之后对话输出部分的效果如下,之后我要对流式输出的结果进行改进,一个一个问题解决。

在这里插入图片描述

        可是即便是第二次及之后运行,其不联网依然会报下面的错误,总之该代码不能实现无网络状态下的流方式输出,这也是一个大坑。

在这里插入图片描述

        根据对代码的分析,最后首先我实现了V1版本的代码,代码如下使用swift中的inference_streamAPI进行流式输出,且可以加载本地的自己的模型,这里再print中加入\r换行符会让每次打印的时候光标出现在行的开头,当输出的文字中没有换行的时候,输出的结果岁月静好。

from modelscope import AutoModelForCausalLM, AutoTokenizer
from swift.llm import  inference_stream,get_template

model_path = "D:\qwen\Qwen-7B-Chat"

tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", trust_remote_code=True).eval()
template_type = 'qwen'
template = get_template(template_type, tokenizer)
history = None

while True:
    query = input('User:')
    gen = inference_stream(model, template, query, history)

    for response, h in gen:
        print(f'\rSystem: {response}',end="")
        history = h
    print()

在这里插入图片描述

        当输出内容过长需要换行的时候结果直接负重前行(自己创造的大坑)。

在这里插入图片描述

4.2 真正实现离线的使用本地模型的多轮对话和流式输出的最终代码

        之后改进了V2版本也是最终版本,代码如下,由于这个代码是我自己悟的可能还有不少可以改进的地方,但是已经可以实现预期的的功能,详细的解释我放在后面 首先再次给出swift安装命令。

pip install ms-swift

        代码部分:

from modelscope import AutoModelForCausalLM, AutoTokenizer
from swift.llm import  inference_stream,get_template

model_path = "D:\qwen\Qwen-7B-Chat"

tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", trust_remote_code=True).eval()
template_type = 'qwen'
template = get_template(template_type, tokenizer)
history = None

before_len = 0

while True:
    query = input('User:')
    gen = inference_stream(model, template, query, history)
    print(f'System:', end="")
    for response, h in gen:

        print(response[before_len:],end="")
        before_len = len(response)
        history = h
    print()

在这里插入图片描述

下面是逐行解释:

  1. from modelscope import AutoModelForCausalLM, AutoTokenizer: 从modelscope库中导入AutoModelForCausalLMAutoTokenizer

  2. from swift.llm import inference_stream, get_template: 从swift.llm模块中导入inference_streamget_template函数。inference_stream用于生成文本流,get_template用于获取特定类型的模板,这里的模板可能是指模型的输入格式或结构。

  3. model_path = "D:\qwen\Qwen-7B-Chat": 定义模型的存储路径。

  4. tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True): 加载预训练的分词器。from_pretrained方法从指定路径加载模型,trust_remote_code=True允许加载远程代码,这通常用于加载自定义的模型或分词器。

  5. model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", trust_remote_code=True).eval(): 加载并准备模型。from_pretrained同样用于从指定路径加载模型,device_map="auto"表示自动选择设备运行模型(如GPU或CPU),trust_remote_code=True同上。.eval()将模型设置为评估模式,通常在预测或评估时使用,以禁用特定于训练的操作如Dropout。

  6. template_type = 'qwen': 定义模板类型,这里为'qwen'

  7. template = get_template(template_type, tokenizer): 获取指定类型的模板。这里的模板可能用于定义输入的格式或者是模型预处理的一部分。

  8. history = None: 初始化历史记录变量,用于存储对话历史,以便模型可以根据之前的交流生成回应。

  9. before_len = 0: 初始化变量,用于记录上一次生成文本的长度。

  10. while True:: 开始一个无限循环,用于连续接收用户输入并生成回应。

  11. query = input('User:'): 接收用户的输入。

  12. gen = inference_stream(model, template, query, history): 调用inference_stream函数,传入模型、模板、用户查询和历史记录,开始生成模型的回应。

  13. print(f'System:', end=""): 打印“System:”,不换行,准备输出模型的回应。

  14. for response, h in gen:: 遍历生成器gen的输出,gen输出的每个元素包含回应和更新后的历史记录。

  15. print(response[before_len:],end=""): 打印新生成的回应部分(去掉之前已经打印的部分),不换行。

  16. before_len = len(response): 更新已打印文本的长度。

  17. history = h: 更新历史记录,以便在下一次迭代时使用。

5.环境配置详细步骤(2024.7.20更新)


后来由于自己电脑重新装了系统,决定重新实现一下部署,结果出现了很多问题,趁着这次就把具体的部署步骤给记录一下,方便日后参考使用。

  • 首先配置一个全局的清华园,之后安装库会快一些
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
  • 之后建一个conda的虚拟环境python版本选择的3.10,最后带小版本编号的是3.10.14
conda create --name llm python=3.10
  • 安装modelscope用于下载模型
pip install modelscope
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
  • 安装官方文档中要求安装的一些依赖
    本来文档里还需要安装deepseed,由于deepspeed库是linux的windows安装不上,然后我发现不按照也不影响运行所以就没安装
pip install transformers==4.32.0 accelerate tiktoken einops scipy transformers_stream_generator==0.0.4 peft
  • 安装流式输出所需要的工具
pip install ms-swift
  • 这个包用于修复huggingface库中的一些bug
conda install chardet

最终流程走完虚拟环境中输入pip list 得到的所有安装上的库的版本信息

absl-py                       2.1.0
accelerate                    0.32.1
addict                        2.4.0
aiohttp                       3.9.5
aiosignal                     1.3.1
aliyun-python-sdk-core        2.15.1
aliyun-python-sdk-kms         2.16.3
async-timeout                 4.0.3
attrs                         23.2.0
binpacking                    1.5.2
Brotli                        1.0.9
certifi                       2024.7.4
cffi                          1.16.0
chardet                       4.0.0
charset-normalizer            2.0.4
click                         8.1.7
colorama                      0.4.6
coloredlogs                   15.0.1
contourpy                     1.2.1
crcmod                        1.7
cryptography                  42.0.8
cycler                        0.12.1
dacite                        1.8.1
datasets                      2.18.0
dill                          0.3.8
docstring_parser              0.16
einops                        0.8.0
filelock                      3.13.1
fonttools                     4.53.1
frozenlist                    1.4.1
fsspec                        2024.2.0
future                        1.0.0
gmpy2                         2.1.2
grpcio                        1.65.1
huggingface-hub               0.24.0
humanfriendly                 10.0
idna                          3.7
importlib_metadata            8.0.0
intel-openmp                  2021.4.0
jieba                         0.42.1
Jinja2                        3.1.4
jmespath                      0.10.0
joblib                        1.4.2
kiwisolver                    1.4.5
Markdown                      3.6
markdown-it-py                3.0.0
MarkupSafe                    2.1.3
matplotlib                    3.9.1
mdurl                         0.1.2
mkl                           2021.4.0
mkl-fft                       1.3.1
mkl-random                    1.2.2
mkl-service                   2.4.0
modelscope                    1.16.1
mpmath                        1.3.0
ms-swift                      2.2.2
multidict                     6.0.5
multiprocess                  0.70.16
networkx                      3.3
nltk                          3.8.1
numpy                         1.24.3
optimum                       1.21.2
oss2                          2.18.6
packaging                     24.1
pandas                        2.2.2
peft                          0.11.1
pillow                        10.4.0
pip                           24.0
protobuf                      4.25.3
psutil                        6.0.0
pyarrow                       17.0.0
pyarrow-hotfix                0.6
pycparser                     2.22
pycryptodome                  3.20.0
Pygments                      2.18.0
pyparsing                     3.1.2
pyreadline3                   3.4.1
PySocks                       1.7.1
python-dateutil               2.9.0.post0
pytz                          2024.1
PyYAML                        6.0.1
regex                         2024.5.15
requests                      2.32.2
rich                          13.7.1
rouge                         1.0.1
safetensors                   0.4.3
scipy                         1.14.0
sentencepiece                 0.2.0
setuptools                    69.5.1
shtab                         1.7.1
six                           1.16.0
sympy                         1.12
tbb                           2021.13.0
tensorboard                   2.17.0
tensorboard-data-server       0.7.2
tiktoken                      0.7.0
tokenizers                    0.19.1
torch                         2.3.1
torchaudio                    2.3.1
torchvision                   0.18.1
tqdm                          4.66.4
transformers                  4.42.4
transformers-stream-generator 0.0.4
trl                           0.9.6
typing_extensions             4.11.0
tyro                          0.8.5
tzdata                        2024.1
urllib3                       2.2.2
Werkzeug                      3.0.3
wheel                         0.43.0
win-inet-pton                 1.1.0
xxhash                        3.4.1
yarl                          1.9.4
zipp                          3.19.2

6.相关文档链接💻


Qwen-7B-Chat模型介绍下载地址
https://modelscope.cn/models/qwen/Qwen-7B-Chat/summary
swift文档地址
https://github.com/modelscope/swift/blob/main/docs/source/LLM/LLM%E6%8E%A8%E7%90%86%E6%96%87%E6%A1%A3.md

2024.3.14更新-相同代码测试了Qwen1.5-1.8B可运行但该模型表现很差

下载完之后换个把文件路径替换一下,直接运行就能使用,我估计14B也可以之后测试一下

下载的时候记得改保存路径,有时候下载之后的模型文件名字会多一些下划线,下完之后到文件夹里看一下模型文件夹的名字。

模型下载地址https://modelscope.cn/models/qwen/Qwen1.5-1.8B/files
在这里插入图片描述

这1.8B模型是个呆子,虽然推理非常快,但其性能几乎做不了任何的任务。

在这里插入图片描述

2024.7.20更新-相同代码测试了Qwen-14B-chat可以使用

虽然推理速度略慢,但是是能带动的,硬件设备还是4070Ti
在这里插入图片描述

2024.7.20更新-BUG修复—HuggingFace报错修复方案

在我复现的时候由于电脑重新安装了系统,出现了以下新的错误信息,在我上GitHub搜索了之后解决方案是安装一个chardet就可以
github issue 网址:https://github.com/comfyanonymous/ComfyUI/issues/2055

Import Error : cannot import name 'create_repo' from 'huggingface_hub'

在这里插入图片描述

conda install chardet

结束

        目前这是我出的第一篇大语言模型的部署的文章,之后会考虑一直更新这个系列,会不定期的完善细节,之后会越来越多的补充,如果有什么问题,欢迎留言探讨。有专业需求可以在公众号上联系我。

  • 93
    点赞
  • 215
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 70
    评论
评论 70
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩浩的科研笔记

这我为您答疑发送资源的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值