deepseek强化学习训练大模型复现-openr1——官方篇(1)

这里记录一下从零配置openr1的过程,需要注意的内容.openr1是huggingface上复现grpo训练大语言模型的成推理模型的一个开源方案,接下来从零实现一下改训练过程
首先把官方的说明先整体认识一下,如果想要直接看本地实现篇,链接:deepseek强化学习训练大模型复现-openr1——本地篇(2)

2025.3.17待校对.

我的目录截至

Open R1

一个完全开源的 DeepSeek-R1 再现项目。这个仓库还在建设中,让我们一起完善它!

目录-openr1官方

  1. 概述
  2. 计划
  3. 安装
  4. 训练模型
  5. 评估模型
  6. 复现 DeepSeek 的评估结果
  7. 数据生成
  8. 贡献

概述

本仓库的目标是完善 R1 流程中缺失的部分,使任何人都能够复现并在此基础上进行开发。项目设计简洁,主要包含以下内容:

  • src/open_r1:包含用于训练、评估模型以及生成合成数据的脚本:
    • grpo.py:在给定数据集上使用 GRPO 训练模型。
    • sft.py:对模型在数据集上进行简单的监督式微调。
    • evaluate.py:在 R1 基准测试上评估模型。
    • generate.py:使用 Distilabel 从模型生成合成数据。
  • Makefile:包含利用上述脚本运行 R1 流程中每一步的便捷命令。

计划

我们将以 DeepSeek-R1 技术报告 为指导,大致分为以下三个主要步骤:

  • 第一步:通过从 DeepSeek-R1 蒸馏高质量语料库来复现 R1-Distill 模型。
  • 第二步:复现 DeepSeek 用于创建 R1-Zero 的纯强化学习 (RL) 流程。这可能需要为数学、推理和代码任务策划新的大规模数据集。
  • 第三步:展示如何通过多阶段训练从基础模型过渡到经过 RL 调优的模型。

在这里插入图片描述

新闻 🗞️

  • ⚡️ [2025/03/11] (更新 #3): 我们发布了 CodeForces-CoTs 数据集,包含 1 万个编程竞赛问题和 10 万个由 R1 蒸馏的解决方案。我们还发布了 IOI24:一个来自国际奥林匹克竞赛的非常困难的题目基准。一个在 CodeForces-CoTs 上训练的 7B Qwen 模型可以在 IOI24 上超越 Claude 3.7 Sonnet,而一个 32B 模型可以超越 R1 本身。
  • ∞ [2025/02/10] (更新 #2): 我们发布了 OpenR1-Math-220k 数据集,包含 22 万个从 NuminaMath 新版本中蒸馏的 R1 推理轨迹。在此数据集上训练的模型与 DeepSeek 的蒸馏模型表现相当。
  • 🔥 [2025/02/02] (更新 #1): 我们实现了 训练推理评估 流程的第一部分。出发!

安装

[!CAUTION]
本项目依赖 CUDA 12.4。如果遇到与段错误相关的错误,请使用 nvcc --version 检查系统是否运行此版本。

要运行本项目中的代码,首先需要使用 uv 创建 Python 虚拟环境。安装 uv 的方法可以参考 UV 安装指南

[!NOTE]
作为快捷方式,运行 make install 可以设置开发所需的库(具体步骤见下文)。安装完成后,您可以尝试使用 Open-R1 模型。

uv venv openr1 --python 3.11 && source openr1/bin/activate && uv pip install --upgrade pip

[!TIP]
对于 Hugging Face 集群用户,将 export UV_LINK_MODE=copy 添加到您的 .bashrc 中,以抑制 uv 的缓存警告。

接下来,安装 vLLM 和 FlashAttention:

uv pip install vllm==0.7.2
uv pip install setuptools && uv pip install flash-attn --no-build-isolation

这还将安装 PyTorch v2.5.1,使用此版本非常重要,因为 vLLM 二进制文件是为此版本编译的。然后,您可以通过 pip install -e .[LIST OF MODES] 为您的特定用例安装其余依赖项。对于大多数贡献者,我们建议:

GIT_LFS_SKIP_SMUDGE=1 uv pip install -e ".[dev]"

接下来,按如下方式登录您的 Hugging Face 和 Weights and Biases 帐户:

huggingface-cli login
wandb login

最后,检查您的系统是否安装了 Git LFS,以便您可以加载模型/数据集并将其推送到 Hugging Face Hub:

git-lfs --version

如果未安装,请运行:

sudo apt-get install git-lfs

训练模型

我们支持使用 DDP 或 DeepSpeed(ZeRO-2 和 ZeRO-3)训练模型。例如,要在从 DeepSeek-R1 蒸馏的带有推理轨迹的数据集(例如 open-r1/OpenR1-Math-220k)上运行 SFT,请运行:

通过命令行训练

accelerate launch --config_file=recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --model_name_or_path Qwen/Qwen2.5-1.5B-Instruct \
    --dataset_name open-r1/OpenR1-Math-220k \
    --learning_rate 1.0e-5 \
    --num_train_epochs 1 \
    --packing \
    --max_seq_length 16384 \
    --per_device_train_batch_size 16 \
    --gradient_checkpointing \
    --bf16 \
    --output_dir data/Qwen2.5-1.5B-Open-R1-Distill

通过 YAML 配置训练

accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/Qwen2.5-1.5B-Instruct/sft/config_demo.yaml

目前,支持以下任务:

  • 监督微调 sft
  • 群组相对策略优化 grpo

[!TIP]
如果您放大/缩小 GPU 的数量,我们建议同时放大每个设备的批量大小或梯度累积步骤的数量,以保持全局批量大小不变。

默认情况下,这些脚本会将每个模型推送到您的 Hugging Face Hub 用户名,即 {username}/{model_name}-{task}。您可以通过将参数附加到命令来覆盖每个 YAML 配置中的参数,如下所示:

更改批量大小、epoch 数等

accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/Qwen2.5-1.5B-Instruct/sft/config_demo.yaml \
    --per_device_train_batch_size=1 --num_train_epochs=5

如果您还想覆盖 Weights and Biases 默认设置,可以按如下方式操作:

accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --config recipes/Qwen2.5-1.5B-Instruct/sft/config_demo.yaml \
    --wandb_entity huggingface --wandb_project open-r1 --run_name Qwen2.5-1.5B-GRPO

[!NOTE]
以下训练命令是为 8 x H100s (80GB) 的节点配置的。对于不同的硬件和拓扑,您可能需要调整批量大小和梯度累积步骤的数量。

SFT

要在从 DeepSeek-R1 蒸馏的带有推理轨迹的数据集(例如 open-r1/OpenR1-Math-220k)上运行 SFT,请运行:

ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/zero3.yaml \
    src/open_r1/sft.py \
    --config recipes/Qwen2.5-1.5B-Instruct/sft/config_demo.yaml

GRPO

要通过 GRPO 训练器进行训练,我们使用一个 GPU 运行 vLLM 以加快生成速度,其余 GPU 用于训练。例如,在具有 8 个 GPU 的节点上,设置 --num_processes 以覆盖 accelerate 配置中的默认值:

ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/zero2.yaml \
    --num_processes=7 src/open_r1/grpo.py \
    --config recipes/DeepSeek-R1-Distill-Qwen-1.5B/grpo/config_demo.yaml

[!WARNING]
蒸馏的 DeepSeek 模型中使用的聊天模板省略了 <think></think> 标签内推理块的内容。它还使用 <think> 预填充了助手响应,这会干扰格式奖励函数。为了解决这个问题,必须覆盖聊天模板,如 recipes/DeepSeek-R1-Distill-Qwen-1.5B/grpo/config_demo.yaml 中所示。

我们提供了一个使用 GRPO 进行数学推理的最小可重现实验,参考了 SimpleRL-Reason 的方法,该方法使用在 8K 示例上训练的 7B 模型。在 8 个 H100 80G GPU 上运行此操作大约需要 3 小时:

ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/zero2.yaml \
    --num_processes=7 src/open_r1/grpo.py \
    --config recipes/Qwen2.5-Math-7B/grpo/config_simple_rl.yaml

我们最终的 模型,虽然使用了不同的学习率、损失函数和奖励结构,但在 MATH-500 上实现了 69.4% 的准确率,表明比基础模型提高了 17% 以上。

👨‍💻 使用代码解释器进行训练

我们提供了一个 code 奖励函数,用于执行训练期间策略生成的代码。目前,此奖励函数针对 Codeforces 等代码竞赛,其中解决方案针对一组测试用例执行,并将整体成功率作为最终奖励返回。为了确保安全执行,我们使用 E2B 沙箱,它们运行速度快且成本低廉。要使用此奖励函数,请首先安装必要的依赖项:

uv pip install -e '.[code]'

然后创建一个 .env 文件,并在其中放置来自 E2B 的 API 令牌:

E2B_API_KEY=“e2b_xxx”

然后确保您的数据集包含一个 verification_info 列,其架构如下(采用自 PrimeIntellect 出色的 数据集 的可验证问题):

在 Slurm 集群上启动作业

如果您有权访问 Slurm 集群,我们提供了一个 slurm/train.slurm 脚本,它将自动为您排队训练作业。以下是如何使用它:

sbatch --job-name=open_r1 --nodes=1 slurm/train.slurm {model_name} {task} {config_suffix} {accelerator}

这里 {model_name}{task} 的定义如上所述,而 {config_suffix} 指的是特定配置,{accelerator} 指的是 recipes/accelerate_configs 中 🤗 Accelerate 配置的选择。如果您想覆盖默认配置参数,可以通过附加一个以空格分隔的字符串(如 '--arg1=value1 --arg2=value2')来提供它们。以下是在 1 个包含 8 个 GPU 的节点上运行 SFT 的具体示例:

在 Slurm 上启动并覆盖默认超参数

sbatch --job-name=open_r1 --nodes=1 slurm/train.slurm Qwen2.5-1.5B-Instruct sft demo zero3 '--per_device_train_batch_size=1 --num_train_epochs=5'

您可以通过增加 --nodes 标志来扩展节点数量。

[!NOTE]
slurm/train.slurm 中的配置针对 Hugging Face 计算集群进行了优化,可能需要进行调整才能适应您自己的计算节点。

评估模型

我们使用 lighteval 来评估模型,自定义任务在 src/open_r1/evaluate.py 中定义。对于适合单个 GPU 的模型,请运行:

MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,max_model_length=32768,gpu_memory_utilization=0.8,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
OUTPUT_DIR=data/evals/$MODEL

AIME 2024

TASK=aime24
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

MATH-500

TASK=math_500
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

GPQA Diamond

TASK=gpqa:diamond
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

LiveCodeBench

lighteval vllm $MODEL_ARGS "extended|lcb:codegeneration|0|0" \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

[!IMPORTANT]
您必须在 vllm 命令中设置 max_model_length=32768,以与我们为每次评估定义的 max_new_tokens 对齐。否则,lighteval 将抛出错误。

要提高跨多个 GPU 的吞吐量,请使用数据并行,如下所示:

NUM_GPUS=8
MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,data_parallel_size=$NUM_GPUS,max_model_length=32768,gpu_memory_utilization=0.8,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
TASK=aime24
OUTPUT_DIR=data/evals/$MODEL
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

对于需要跨 GPU 分片的超大型模型,请使用张量并行并运行:

NUM_GPUS=8
MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,tensor_parallel_size=$NUM_GPUS,max_model_length=32768,gpu_memory_utilization=0.8,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
TASK=aime24
OUTPUT_DIR=data/evals/$MODEL
export VLLM_WORKER_MULTIPROC_METHOD=spawn
lighteval vllm $MODEL_ARGS "custom|$TASK|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

您还可以使用 make evaluate 启动评估,指定模型、任务,以及可选的并行技术和 GPU 数量。

在单个 GPU 上进行评估:

make evaluate MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B TASK=aime24

使用数据并行:

make evaluate MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B TASK=aime24 PARALLEL=data NUM_GPUS=8

使用张量并行:

make evaluate MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B TASK=aime24 PARALLEL=tensor NUM_GPUS=8

复制 Deepseek 的评估结果

[!NOTE]
DeepSeek-R1 论文使用每个查询 64 个响应的采样来估计 pass@1。下面,我们报告了每个查询采样 1 个响应的结果,这可能解释了我们的结果与他们的结果之间 1-3σ 的小差异。

AIME 2024

我们能够在 ~1-3 个标准差内重现 Deepseek 在 AIME 2024 基准测试中报告的结果:

模型AIME 2024 (🤗 LightEval)AIME 2024 (DeepSeek Reported)
DeepSeek-R1-Distill-Qwen-1.5B26.728.9
DeepSeek-R1-Distill-Qwen-7B56.655.5
DeepSeek-R1-Distill-Qwen-14B60.069.7
DeepSeek-R1-Distill-Qwen-32B73.272.6
DeepSeek-R1-Distill-Llama-8B43.350.4
DeepSeek-R1-Distill-Llama-70B73.370.0

要重现这些结果,请使用以下命令:

NUM_GPUS=1 # 32B 和 70B 模型设置为 8
MODEL=deepseek-ai/{model_name}
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,max_model_length=32768,gpu_memory_utilization=0.8,data_parallel_size=$NUM_GPUS,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
OUTPUT_DIR=data/evals/$MODEL

lighteval vllm $MODEL_ARGS "custom|aime24|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

或者,您可以按如下方式启动 Slurm 作业:

python scripts/run_benchmarks.py --model-id {model_id}  --benchmarks aime24

MATH-500

我们能够在 ~1-3 个标准差内重现 Deepseek 在 MATH-500 基准测试中报告的结果:

我们能够在 ~1-3 个标准差内重现 Deepseek 在 MATH-500 基准测试中报告的结果:

模型MATH-500 (🤗 LightEval)MATH-500 (DeepSeek Reported)
DeepSeek-R1-Distill-Qwen-1.5B84.683.9
DeepSeek-R1-Distill-Qwen-7B93.092.8
DeepSeek-R1-Distill-Qwen-14B95.093.9
DeepSeek-R1-Distill-Qwen-32B96.694.3
DeepSeek-R1-Distill-Llama-8B88.689.1
DeepSeek-R1-Distill-Llama-70B96.494.5

要重现这些结果,请使用以下命令:

NUM_GPUS=1 # 32B 和 70B 模型设置为 8
MODEL=deepseek-ai/{model_name}
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,max_model_length=32768,gpu_memory_utilization=0.8,data_parallel_size=$NUM_GPUS,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
OUTPUT_DIR=data/evals/$MODEL

lighteval vllm $MODEL_ARGS "custom|math_500|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

或者,您可以按如下方式启动 Slurm 作业:

python scripts/run_benchmarks.py --model-id {model_id}  --benchmarks math_500

GPQA Diamond

我们能够在 ~1-3 个标准差内重现 Deepseek 在 GPQA Diamond 基准测试中报告的结果:

模型GPQA Diamond (🤗 LightEval)GPQA Diamond (DeepSeek Reported)
DeepSeek-R1-Distill-Qwen-1.5B34.333.8
DeepSeek-R1-Distill-Qwen-7B50.549.1
DeepSeek-R1-Distill-Qwen-14B59.659.1
DeepSeek-R1-Distill-Qwen-32B63.662.1
DeepSeek-R1-Distill-Llama-8B52.049.0
DeepSeek-R1-Distill-Llama-70B67.265.2

要重现这些结果,请使用以下命令:

NUM_GPUS=1 # 32B 和 70B 模型设置为 8
MODEL=deepseek-ai/{model_name}
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,max_model_length=32768,gpu_memory_utilization=0.8,data_parallel_size=$NUM_GPUS,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
OUTPUT_DIR=data/evals/$MODEL

lighteval vllm $MODEL_ARGS "custom|gpqa:diamond|0|0" \
    --custom-tasks src/open_r1/evaluate.py \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

python scripts/run_benchmarks.py --model-id {model_id}  --benchmarks gpqa

LiveCodeBench

我们能够在 ~1-3 个标准差内重现 Deepseek 在 LiveCodeBench 代码生成基准测试中报告的结果:

模型LiveCodeBench (🤗 LightEval)GPQA Diamond (DeepSeek Reported)
DeepSeek-R1-Distill-Qwen-1.5B16.316.9
DeepSeek-R1-Distill-Qwen-7B36.637.6
DeepSeek-R1-Distill-Qwen-14B51.553.1
DeepSeek-R1-Distill-Qwen-32B56.657.2
DeepSeek-R1-Distill-Llama-8B37.039.6
DeepSeek-R1-Distill-Llama-70B54.557.5

要重现这些结果,请使用以下命令:

NUM_GPUS=1 # 32B 和 70B 模型设置为 8,或者使用 data_parallel_size=8 加速较小模型
MODEL=deepseek-ai/{model_name}
MODEL_ARGS="pretrained=$MODEL,dtype=bfloat16,max_model_length=32768,gpu_memory_utilization=0.8,data_parallel_size=$NUM_GPUS,generation_parameters={max_new_tokens:32768,temperature:0.6,top_p:0.95}"
OUTPUT_DIR=data/evals/$MODEL

lighteval vllm $MODEL_ARGS "extended|lcb:codegeneration|0|0" \
    --use-chat-template \
    --output-dir $OUTPUT_DIR

python scripts/run_benchmarks.py --model-id {model_id}  --benchmarks lcb

数据生成

从小型蒸馏 R1 模型生成数据

以下示例可以在 1xH100 中运行。
首先安装以下依赖项:

uv pip install "distilabel[vllm]>=1.5.2"

现在将以下代码段保存到名为 pipeline.py 的文件中,并使用 python pipeline.py 运行它。它将为 10 个示例中的每一个生成 4 个输出(将存储库的用户名更改为您的组织/用户名):

from datasets import load_dataset
from distilabel.models import vLLM
from distilabel.pipeline import Pipeline
from distilabel.steps.tasks import TextGeneration

prompt_template = ///
	"""
	您将获得一个问题。请逐步推理,并将您的最终答案放在 \\boxed{}: 中:
	{{ instruction }}
	"""

dataset = load_dataset("AI-MO/NuminaMath-TIR", split="train").select(range(10))

model_id = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"  # 替换为另一个小型蒸馏 r1

with Pipeline(
    name="distill-qwen-7b-r1",
    description="一个从蒸馏 r1 模型生成数据的管道",
) as pipeline:

    llm = vLLM(
        model=model_id,
        tokenizer=model_id,
        extra_kwargs={
            "tensor_parallel_size": 1,
            "max_model_len": 8192,
        },
        generation_kwargs={
            "temperature": 0.6,
            "max_new_tokens": 8192,
        },
    )
    prompt_column = "problem"
    text_generation = TextGeneration(
        llm=llm, 
        template=prompt_template,
        num_generations=4,
        input_mappings={"instruction": prompt_column} if prompt_column is not None else {}
    )

if __name__ == "__main__":
    distiset = pipeline.run(dataset=dataset)
    distiset.push_to_hub(repo_id="username/numina-deepseek-r1-qwen-7b")

查看 HuggingFaceH4/numina-deepseek-r1-qwen-7b 的示例数据集。

从 DeepSeek-R1 生成数据

要运行更大的 DeepSeek-R1,我们使用了 2 个节点,每个节点有 8×H100 GPU,使用此存储库中 slurm/generate.slurm 的 slurm 文件。首先,安装依赖项:

(目前我们需要安装 vllm dev wheel,它修复了 R1 cuda 图捕获

pip install https://wheels.vllm.ai/221d388cc5a836fa189305785ed7e887cea8b510/vllm-1.0.0.dev-cp38-abi3-manylinux1_x86_64.whl --extra-index-url https://download.pytorch.org/whl/cu121
uv pip install "distilabel[vllm,ray,openai]>=1.5.2"

然后运行以下命令:

sbatch slurm/generate.slurm \
    --hf-dataset AI-MO/NuminaMath-TIR \
    --temperature 0.6 \
    --prompt-column problem \
    --model deepseek-ai/DeepSeek-R1 \
    --hf-output-dataset username/r1-dataset

[!NOTE]
作业运行时,您可以通过集群登录节点设置 SSH 隧道,从运行 ssh -L 8265:ray_ip_head_node:8265 <login_node> 的计算机访问 Ray 仪表板,然后浏览 http://localhost:8265

贡献

欢迎贡献。请参阅 https://github.com/huggingface/open-r1/issues/23。

致谢

该项目是开放 AI 社区中许多团体和个人共同努力的成果。我们特别感谢 vLLM 和 SGLang 团队创建了高性能工具来扩展 GRPO 的推出。我们还要感谢 OpenThoughtsPrime IntellectGeneral Reasoning 团队创建和共享高质量的推理数据集。

引用

如果您发现此项目在您的工作中很有用,请考虑如下引用:

@misc{openr1,
title = {Open R1: DeepSeek-R1 的完全开放复制},
url = {https://github.com/huggingface/open-r1},
author = {Hugging Face},
month = {January},
year = {2025}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白云千载尽

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值