快速了解生成式AI

荐语

本文要介绍的是,O’Reilly在2024年出版的书籍,《Generative AI in Action》,作者是来自微软的Amit Bahree。

书中主要介绍了生成式AI的相关知识,涉及LLM、提示工程、模型微调、RAG、向量数据库等内容,作者给出了大量的代码示例,通过实战的方式带读者入门生成式AI。

生成式AI领域发展迅速,虽然本书是在2024年11月出版,但现在看来,书中介绍的技术已经算是“老旧”的了。不过,跟着作者的思路,读者能够快速理清整个生成式AI的技术脉络,有助于后续展开更深入的了解。

生成式AI概述

随着大模型LLM的大热,生成式AI(Generative AI,GenAI)近年来获得了越来越多的关注和普及。如下图所示,生成式AI是AI的一个子领域,演变自深度学习。

传统的机器学习基于统计学对数据进行预测;

深度学习基于神经网络模拟人脑行为,去执行复杂的任务;

生成式AI则可以从数据中创作,就像我们人类一样

如下列出了生成式AI与传统AI的一些区别:

传统AI生成式AI
用途专注预测和分类任务从原始数据中创造不存在的内容
硬件所需算力较少,能够在各种硬件上运行需要大量算力,通常运行在大规模的计算集群上。
训练数据较小的标记数据集大型的原始数据集
模型复杂度百万级以下的参数数量亿级以上的参数数量

很多人会错误地把ChatGPT与生成式AI划上等号,实际上,ChatGPT只是生成式AI最简单的应用。生成式AI能做的很多,个人层面,常见的如文字、图像、视频、代码、音乐的生成;企业层面,常见的如个性化营销、消费者服务、风险管控、合同管理等。

总而言之,生成式AI能够弥补传统AI的局限性,帮助用户和企业构建更加智能的应用。

在生成式AI领域中,大语言模型(LLM)作为大脑,能够生成出符合用户需求的内容,下文将简单介绍其原理。

大语言模型

大语言模型(Large Language Models,LLM)是生成式AI的基础,它由基础模型(Foundational model,FM)发展而来,后者在2021年被首次提出。

过去的AI模型通常只能应用于特定的任务,而FM则在此基础上做了泛化性优化,通过大数据量的训练得到了更强的适应性。

早期最具代表性的FM为Google开发的BERT模型,它被广泛应用于自然语言理解(NLU)任务,比如文本分类、命名实体识别等。

LLM是适用于自然语言处理(NLP)和生成(NLG)任务的基础模型,它的模型规模更大,包括参数数量、训练数据集大小、算力资源。

通常,LLM都会在名称上带上参数规模,比如Meta的Llama 2-70B,其中7B表示参数规模为700亿。

一般来说,模型参数越多,性能就越好,最近国产大模型DeepSeek V3甚至已经达到了671B规模。

当然,模型规模越大,就要消耗越多的算力资源,也就意味着更高的经济成本。因此,在一些任务较为简单或明确的场景,用户可能会偏向使用成本效率更优的小语言模型(Small language model,SLM),比如微软最近推出的Phi-4模型,它的参数规模只有14B,但得益于多方面的技术进步,它在数学推理方面超越了同类和更大规模的模型。

LLM的本质是利用当前上下文去猜测下文,但它并不像人类一样能够直接读懂自然语言。因此,必须把输入文本(Prompt)先分块(token),这样才能得到更好的泛化性,接着把它们转换成能理解的格式(Embedding),最后通过特定的算法(Transformer)去猜测出下文。

Token序列

当前,几乎所有的LLM都是基于token的架构,它是LLM处理文本的基本单位。

有多种将文本划分成token序列的方法,常见的如按字划分、按词划分、按句划分等。

划分的粒度越细,模型的泛化性也会更好,但token数量会更多,所需计算资源更大;

划分的粒度越粗,token保留的语义和上下文也就更多,数量也会更少,但遇到陌生词或多义词可能无法处理,依赖构建好的词典。

因为token的数量与计算资源挂钩,所以模型对单次处理的最大token数量都会有限制,比如GPT-4o支持的最大token数为128K,而Llama 2则是4K。

Embedding向量

完成token划分后,还需要将它们转换成LLM能够识别和处理的向量形式,称为Embedding。

Embedding背后的思想是,具有相似含义的token应该有着相似的向量表示,它们的相似程度可通过向量的距离来衡量

Embedding模型负责将token转换为Embedding,Embedding模型的构建也需要经过数据收集、预处理、特征提取、训练等一系列的流程。

以“床前明月光,疑是地上霜。”为例子,我们按词进行token划分,并提前构建好一张词表[“床前”,“明月”,“光”,“,”,“疑是”,“地上”,“霜”,“。”],那么“明月”可以简单表示为[0,1,0,0,0,0,0,0],同理,“地上”可以表示为[0,0,0,0,0,1,0,0]

若把“床前明月”作为Transformer的输入,那么可能得到如下的输出Embedding,[0.2, 0.4, 0.9, 0.5, 0.1, 0, 0.3, 0.1],其中“”的概率最大,因此下一个token为“”。

Transformer架构

Transformer架构是LLM的基石,它使用一种被称为多头注意力(Multi-Head Attention,MHA)的机制来考虑整个Prompt(后文统称提示)上下文,能够有效捕捉token之间的依赖关系,从而具备了极佳的语言理解能力。

Transformer架构的原理图如上,分为Encoder和Decoder两部分,原理图很复杂。为简单起见,我们先忽略Add&Norm、Feed Forward、Linear、Softmax,可以把它们都看成是标准化和维度对齐的模块。

Encoder的输入是Prompt的Embeddings(用Ei表示),经过MHA机制找到E的隐藏状态,随后作为Decoder的输入预测的下个token的Embedding(用Eo1表示),再以Ei+Eo1去预测下下个token(Eo2),不断迭代。

我们注意到,Embedding要先经过Positional Encoding才会输入到MHA上,那么Positional Encoding的作用是什么呢?

一般来说,一个句子的语义,与词在句子中的顺序强相关,比如“你知道不”和“你不知道”的语义完全不同。因此,我们需要为Embeddings加入位置信息,这就是Positional Encoding的作用。

MHA背后的核心思想是从多个角度(Multi-Head)来找到句子中各个词(token)之间的深层语义关系(Attention),并以此来预测下一个词。

多角度通过向量的线性变换实现,这得益于一个向量在线性变换后挖掘到它的一些隐藏特征,但本质还是一样。

比如,对于“床前明月光”和“疑是地上霜”,从语义的角度来看,“床前”与“地上”具备相似性;从韵律角度看,“”和“”具备相似性。

对于输入的向量E,下图展示如何通过注意力机制把深层的语义关系凸显出来了:

上图对注意力计算做了简化,QKV都是由E线性变换而来,忽略掉标准化和维度对齐后,可认为它们维度相同。

首先是QK进行点积运算,对于两个向量的点积运算结果,相似度越高则值越大。因此,如果两个词语义相似度越高,它们Embedding的点积运算结果也就越大。最后将它(权重)与V相乘,就能把V中的深层语义关系凸显出来。

一次注意力计算是一个头,进行多次注意力计算后把结果合并在一起,就是多头注意力机制。经过多次计算,也就相当于从多个角度挖掘语义关系,最终的结果也会更加的准确

根据Transformer的算法流程,每次计算需要对所有的token进行注意力计算。比如,输入为“床前”,对它进行注意力计算后得到“明月”,下一轮预测时,会把它们拼在一起,“床前明月”,随后进行计算,得到“”。

其实,“床前”在上一轮预测时已经计算过,完全可以把结果缓存下来,下次只需计算“明月”即可,这就是KV Cache的原理

至于为什么不用缓存Q,原理如下图所示:

LLM的局限

LLM虽然很强大,但也有它的局限性:

  • 缺失时效性。LLM强大的生成能力依赖于用于训练的数据,一旦训练结束,知识便不再更新,而且也无法进行外部搜索,缺失时效性。
  • 幻觉问题。对上下文的理解不足或缺少专业领域的知识,可能导致LLM“自信”地生成不准确或不存的结果。

下面,我们举一个因缺少上下文导致的幻觉问题的例子。

假设你是一名中学生,春节假期需要写一篇以春节为主题的文章,着重描写家乡的习俗,500字左右。

现在你想让LLM帮你完成文章的写作,可以输入如下的提示:

> “写一篇关于春节的文章

以下为GPT-4o mini模型的输出:

模型输出泛泛对春节进行了介绍,缺少细节描写,显然不满足你心里的要求。

导致这种“幻觉”现象的重要原因是给模型输出的上下文不足,你只是提示它写一篇以春节为主题的文章,但并未提出更细节的要求(着重描写家乡的习俗等)。

下面,我们丰富提示:

>“现在你是一名语文成绩优异的中学生,现在要以类似汪曾祺的文笔写一篇以春节为主题的作文,字数在500字左右。你的家乡是广东,文章要着重描写广东的春节年夜饭的习俗,介绍常见的年夜饭菜式,然后着重描写白切鸡的做法、味道,能够突出食物的色香味,抒发对家乡的思念之情,作文不需要副标题。

模型输出如下:

显然,输出的质量大幅提高,这种通过优化提示来提升LLM生成内容质量的方法,就是提示工程(Prompt Engineering)。

提示工程

提示(Prompt)是LLM的输入,用于引导LLM完成内容生成。而提示工程(Prompt Engineering)是指通过精心设计的提示来提升输出的质量

其核心思想是为提示提供更加丰富的上下文信息,旨在帮助模型更好地理解用户的意图

最简单的提示工程是人工设计好模板,在提问时基于模板编写提示。

一个好的提示通常把包含如下几个要素:

  • 指令(instruction):模型执行的任务或问题,比如前文例子中的“写一篇以春节为主题的文章”。
  • 主体内容(primary content):模型执行的主要内容,是对指令更详细的补充,比如前文例子中的“文章要着重描写广东的春节年夜饭的习俗,介绍常见xxx
  • 指引(cue):对指令和主体内容的补充,提供一些“限制”,有助于比如前文例子中的 “以类似汪曾祺的文笔”、“作文不需要副标题”等。
  • 附加内容(supporting content):可以在提示中注入一些专业领域或最新知识等的附加内容,以保证模型输出更准确。
  • 样例(example):模型生成响应的样例,让LLM有迹可循。

不同应用场景的提示模板各异,比如中学写作场景,要提示LLM“你是一名中学生”,在医疗场景,则要提示LLM“你是一名医生”。

另外,提示模板的设计也是一个不断迭代的过程,这通常需要借助一些软件框架来实现自动化,比如Prompt Flow、LangChain等。

提示工程是一种较为轻量级的优化方法,它无需修改模型的参数,进通过给定的提示引导模型输出。然而,提示工程并不总是有效。

LLM生成内容的质量与训练数据强相关,提示工程的本质是引导,如果训练模型的数据缺乏专业的医疗知识,即使再好的提示,也难以引导模型输出高质量的医疗问答结果。

这里的“再好的提示”并不包含引入高质量的附加内容,有一种被称为检索增强生成(RAG)的技术可以实现,将在后文介绍。。

针对这种场景,我们可以用专业的医疗数据集对模型进行二次训练,让它的能力更强,这个过程称为模型微调。

模型微调

LLM通过接受大量通用的数据训练(预训练模型),实现对自然语言的广泛理解,保证了系统的泛化性,但也因此可能在某些专业领域表现不佳。

模型微调(Fine-tune)是指在已有的预训练模型(比如GPT-4o、Llama 3.3等)基础上,使用特定的数据集进行二次训练,以调整模型参数,使其能够在特定领域的任务上表现更好

模型微调大致可以分成两类:

  • 全微调(Full Fine-tuning),对模型进行全面的二次训练,会更新所有参数。
  • 低秩自适应(Low-rank adaptation,LoRA) ,允许在保持模型权重不变的情况下,利用较少的可训练参数实现有效的微调。

全微调和LoRA之间的选择是一种权衡,前者微调效果更好,但计算成本更大;后者通过牺牲了一定的准确性,但实现计算成本的大幅降低。

如上所述,模型微调的流程也是一个不断迭代的过程,主要有如下几个关键步骤:

  1. 选择基础模型和微调方法。根据具体的应用场景,选择合适的基础模型和微调方法,通常需要考虑模型对任务的适应性、数据集大小、基础设施等因素。比如,如果中文问答应用,最好选择中文支持更好的Qwen,而不是Llama。
  2. 数据准备。主要对数据集的清晰、标准化、格式转换等预处理步骤。
  3. 微调。模型微调的实际过程,涉及对模型的二次训练。
  4. 评估。评估微调效果,如果效果不佳,则调整参数重新微调。评估的常见指标通常包含结果准确性、逻辑连贯性、语言流畅度等。
  5. 部署。评估通过后,模型即可部署并投入生产。

模型微调的成本是巨大的,下图展现了模型训练的几个阶段以及所需的计算和时间成本:

对于一些时效性要求很高的应用,为保证模型能够时刻包含最新的知识,需要不断对模型进行微调。

一方面,微调的是非常耗时(数天),时效性无法满足要求;另一方面,反复微调的巨大成本也是用户无法接受的。

如果有一种方法,能够让LLM“自动”去检索最新知识,并以此作为输入生成结果,这样既能保证时效性,又能避免高昂的微调成本,就好了!

检索增强生成(Retrieval-Augmented Generation,RAG)就是这样的技术。

检索增强生成

检索增强生成(Retrieval-Augmented Generation,RAG)是一种利用信息检索来优化LLM输出的技术,通过在生成结果之前引用训练数据之外的知识库,丰富了上下文,从而增强生成内容的准确性。

前文提到,提示有一项关键要素附加内容,能够为LLM提供训练数据之外的上下文。

RAG的本质就是根据用户查询,从外部知识库中检索相关的知识,随后以附加内容的形式添加到提示中,增强LLM的生成内容

RAG基本工作流

前文提到,在LLM中,文本会被转换成向量来捕捉深层语义关系,RAG中也一样,文本和外部知识都要先被转换成向量来处理:

如上图所示,RAG的工作流分成索引、检索、生成两个阶段。

(一)索引阶段

索引阶段就是将外部知识按照特定的数据结构组织起来,实现更高效的检索。主要有以下几个步骤:

1、文本分块。原始文本往往都有冗长、信息量大等特点,比如一本书,这并不利于高效检索。一方面干扰信息太多,影响检索精度;另一方面检索过程计算开销很大。文本分块可以将长文本切分成多个粒度更细的文本块,能够更准确匹配用户查询意图的同时,计算和存储开销也更小。

2、Embedding。通过Embedding模型将文本块转换成向量(Embedding)。

3、索引。对向量按照特定的数据结构建立索引,比如基于图的HNSW、基于哈希桶的LSH、倒排索引IVF等。

4、存储。将原始向量和索引数据存储起来,可以使用专用的向量数据库,比如Milvus等,也可以使用传统数据库+向量索引插件,比如PostgreSQL+pgvector。

(二)检索阶段

检索阶段就是利用查询去检索相关的文本块的过程,主要有以下2个步骤:

1、Embedding。使用与索引阶段同样的Embedding模型,将原始查询转换成向量。

2、检索。利用向量相似性计算,找到与原始查询最匹配的TopN个相关文本块。

(三)生成阶段

生成阶段首先将相关文本块与原始查询组成新的提示,引导LLM基于相关文本块完成内容的生成。

基于上述流程的RAG,我们很容易回答这种问题:“广州的标志性建筑是什么?

但对于下面这类多跳推理或全局摘要问题,可能难以回答:“深圳所在的省份的省会的标志性建筑是什么?”,“广东各个省份的标志性建筑是什么?”。

因为这需要结合多个文本块(可能向量并不相似)完成答案的生成。

这体现了仅仅基于向量相似性检索的传统RAG的局限性:

  • 忽视关系。文本块往往不是孤立的,而是相互关联的,仅仅基于向量检索无法难以捕捉具备高度结构化关系的知识。
  • 缺乏全局信息。基于向量检索只能检索文本的子集,无法获取全局信息,难以完成诸如全局摘要等任务。

对于建立关系,我们很容易联想到知识图谱(Knowledge Graph),它将数据按照图的结构组织起来,实体就是图的顶点,关系就是图的边。

为RAG引入知识图谱

RAG与知识图谱的结合归属到GraphRAG,它是RAG的一个重要分支,旨在按照图/知识图谱的形式组织文本,考虑了文本间的互联,从而能够更准确地捕捉文本间的深层联系;另外,还能通过识别子图或社区,获取全局的信息,从而能够应对全局摘要等场景。

GraphRAG的实现方案有很多种,下面我们重点介绍微软开源的实现(https://github.com/microsoft/graphrag)。

如上图所示,GraphRAG与传统RAG的区别主要体现在索引和检索阶段。

(一)索引阶段

1、利用LLM从文本块中完成知识图谱的提取,并以图的形式存储起来。

微软GraphRAG通过Parquet数据表的形式存储在磁盘中,并未用到图数据库。

2、利用Leiden算法识别多层级社区,并利用LLM为每个社区生成社区摘要,便于后续生成阶段的处理。

3、将知识图谱的实体、关系、社区摘要、文本块等通过Embedding模型转换成向量,存储到向量数据库中。

微软GraphRAG目前实现可对接Azure AI Search、Azure Cosmosdb和LanceDB(只能单机部署)。

(二)检索阶段

按照查询的类别,多跳推理类查询使用本地查询(Local Search),全局摘要类查询使用全局查询(Global Search):

1、本地查询。根据查询从向量数据库中检索出起始实体,随后在知识图谱中它们作为起点,检索其他相关实体和关系,并以此作为提示的附加内容。

2、全局查询。针对各个社区摘要,通过LLM进行并行初步汇总,生成中间结果,随后在生成阶段完成最终汇总。

微软GraphRAG的缺点很明显,它在索引和查询阶段都频繁使用了LLM,导致高昂的计算成本。

为此,微软在2024年底发布了优化版LazyGraphRAG,通过,1)在索引阶段使用轻量级的NLP算法完成知识图谱的抽取、2)在查询阶段对原始查询进行子查询拆解来提升查询效率等技术手段,保证查询准确度不下降的同时,大幅降低了成本。

到目前为止,不管是传统RAG还是GraphRAG,每一次用户查询都只检索一次,在一些复杂的查询任务,结果可能依然不够准确

如果能够建立一种反馈机制,当评估本次检索不满足要求时,自动修正检索条件,并执行下次检索,经过多轮迭代,获得高质量检索结果的概率将会大幅提升。

为RAG引入反馈机制

为RAG引入反馈机制,需要一个评估模块,用于评估检索结果的质量,并决定下一步的执行策略:

我们很容易想到用AI Agent来进行评估和决策,这正式它擅长的。

AI Agent是一种能够感知环境、进行决策和执行动作的智能实体。它能够分析环境信息和数据(检索结果),自动执行任务并优化行为(决定终止或继续迭代),已实现特定目标(返回高质量的检索结果)。

RAG与AI Agent结合被称Agentic RAG,除了评估和决策,它还能进行查询拆分、查询路由、信息检索等。

AI Agent的集成为RAG带来了极强的灵活性,可以根据用户需求,很方便地扩展新功能。

当然,Agentic RAG也会带来系统复杂性和计算资源的增加,总之,没有十全十美的RAG方案,一切尽在权衡

回顾RAG的技术演进

回顾前文,从传统RAG,到GraphRAG,再到Agentic RAG,这一步步的优化对应着RAG的三种范式的演进。

(一)Native RAG

Native RAG是最早的范式,遵循Index(索引)->Retrieval(检索)->Generation(生成)的传统范式。如前文所述,它在一些复杂的场景(多跳推理、全局摘要等)依然存在检索准确度低的问题。

(二)Advanced RAG

Advanced RAG在Native RAG的基础上增加了检索前处理(Pre-Retrieval)和检索后处理(Post-Retrieval)步骤,一定程度上克服了Native RAG的局限:

  • 检索前处理主要优化索引结构(比如GraphRAG引入知识图谱)和原始查询优化(比如LazyGraphRAG的子查询拆分)。
  • 检索后处理主要对检索结果进行重排序或者总结提炼,从而进一步提升上下文的准确性。

(三)Modular RAG

Modular RAG则在前两种范式的基础上,提供了更强的自适应能力,支持灵活地编排检索工作流,以应对不同的场景。

到目前为止,我们发现,不管是哪种RAG范式,都离不开向量检索。因为向量是AI模型的语言,文本、图片、视频需要被转成向量才能供LLM使用。而提供向量检索能力的关键组件是向量数据库(vector database)。

向量数据库

向量数据库(vector database)是一种用于存储、管理和查询高维向量的数据,能够高效地进行相似性检索。

向量数据库可分成两种:

  • 专门为向量检索设计的专用数据库,如Milvus、Weaviate、Pinecone等
  • 支持向量检索功能的常规数据库,如PostgreSQL(通过pgvector插件)、Elasticsearch等。

随着生成式AI的火爆,向量数据库近两年也越来越受欢迎,越来越多的常规数据库开始支持向量检索功能;而随着应用场景的丰富,专用向量数据库也开始支持标量查询、全文检索等常规数据库的功能。

综合型的向量数据库逐渐成为一种趋势

向量数据库主要利用了向量相似性的原理,前文已有相关介绍,这里不再展开。

基于生成式AI的软件架构

过去,从单体时代、到服务化时代、再到云原生时代,企业级软件架构经历了几次重大变革,以满足对业务不断变化的需求。

如今,生成式AI的兴起将促进新的一轮软件架构变革

书中作者将基于生成式AI的软件架构定义如下:

AI基础设施层

AI基础设施层(AI infrastructure)是一切的动力来源,包含支持生成式AI应用程序开发和部署的硬件(XPU、内存、存储等)、软件(编译器、OS、容器等)和服务(可观测服务等)。

它通常会针对生成式AI的工作负载进行优化,并且具备能够支持LLM训练和推理的高性能计算能力。

基础模型层

基础模型层(Foundational models)包含了各类基础模型:

可以是性能卓越的大模型LLM,比如DeepSeek V3 671B、Llama 3.1 405B等。

也可以是面向边缘/端侧的小模型SLM,比如Phi-4 14B、Gemma-2 2B等。

或者是面向专业领域微调的模型,比如面向医疗的MMedLM、Med-PaLM v2.0等。

编排层

编排层(Orchestration)是整个架构的关键,负责任务分配、资源管理和工作流程优化等,包含Response filtering、Meta prompt、Grounding和Plugin execution四个组件。

  • Response filtering。对基础模型的提示和响应进行分析、过滤和优化,确保返回给用户的响应是准确、安全的。
  • Meta Prompt。为基础模型提供额外的信息和约束,可以是用户设置或者系统自动生成,提示工程属于这一层。
  • Grounding。用于确保响应与用户指定的上下文相关,RAG属于这一层。
  • Plugin execution。为系统提供更多的功能,比如数据检索、格式化、校验等。RAG所依赖的向量数据库属于这一层。

当前,业界已经涌现了很多编排框架,比如LangChain、Llama-Index、Hugging Face等

Clopilot用户体验层

Clopilot,AI副驾驶,是生成式AI中的一个重要概念,旨在增强人类的能力和创造力。

Clopilot用户体验层(Clopilot UX)向用户提供强大、易用的AI工具链/界面,根据不同的应用场景,有着不同的运行模式,比如用于辅助编码的Github Copilot、用于辅助办公的Microsoft 365 Copilot等。

最后

生成式AI仍在迅速发展。

前不久发布的国产大模型DeepSeek V3火爆全网,通过FP8 混合精度训练、多令牌预测等技术手段,在保证高性能的同时大幅降低了成本。

Google最新发布的Titans架构旨在解决现有Transformer架构在处理长序列数据时的记忆瓶颈问题,号称是后者的继任者。

提示工程也在不断与Chain of Thought等技术相结合,应对更为复杂的场景。

模型微调并未因为RAG的出现而消失,它们在不同的应用场景发挥着重大的作用。

据中国互联网络信息中心(CNNIC)调查,截至2024年12月,我国生成式AI应用的用户规模达2.49亿人,占整体人口17.7%。

生成式AI的时代已经来临

参考

[1] Generative AI in Action, Amit Bahree

[2] Attention Is All You Need, Ashish Vaswani, etc.

[3] https://www.zhihu.com/question/596900067, 看图学

[4] Retrieval-Augmented Generation for Large Language Models: A Survey, Yunfan Gao, etc.

[5] Modular RAG: Transforming RAG Systems into LEGO-like Reconfigurable Frameworks, Yunfan Gao, etc.

[6] Graph Retrieval-Augmented Generation: A Survey, Boci Peng Boci, etc.

[7] CNNIC报告:生成式AI产品用户规模达2.49亿人, 南方都市报

更多文章请关注微信公众号:元闰子的邀请

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值