隐语课程学习笔记4-隐语安装部署及实操讲解

本周开启隐语的第四次课程学习,关于隐语的安装部署及简单体验。

1. 隐语部署模式

对于隐私计算开发以及业务生成场景使用,提供两种不同的模式:

        (1)仿真模式,包括单机仿真以及集群仿真。

                  仿真模式具备很多优势。在这点上,业内的隐私计算厂商基本都有提供,但隐语可能在

                  这方面体验感会更好一些,投入了更多的资源去完善。

                  a. 成本低

                       开发者:在仿真模式下,开发者可以在单机或集群环境中模拟生产环境,进行调试

                                      和测试,避免了直接在真实数据上操作的高成本和高风险。
                       使用者:可以在仿真模式下熟悉平台的功能和操作流程,而无需承担数据泄露或系

                                      统故障的风险。
                  b. 高效调试

                       开发者:可以在仿真模式下快速迭代开发和测试代码,查找和解决问题,提升开发

                                      效率。
                       使用者:可以快速验证其应用程序或流程在仿真环境中的表现,确保在投入生产前

                                      已经过充分测试。
                  c. 安全性

                       开发者:仿真模式下使用的是模拟数据或脱敏数据,降低了实际数据泄露的风险。
                       使用者:在进行功能测试和性能测试时,无需担心实际数据的安全性问题。

        (2)生产模式,多机部署执行。更加注重安全性以及真实环境。        

                  a. 安全增强

                      开发者:生产模式下所有参与方都需要执行代码,并且平台提供了额外的安全增强措

                                    施,如数据加密、访问控制等,确保数据传输和处理的安全性。
                      使用者:在生产模式下,用户的数据得到了严格保护,符合企业和行业的安全标准和

                                     合规要求。
                   b. 高可靠性

                       开发者:生产模式经过严格测试和验证,能够在高负载下稳定运行,确保系统的可

                                      靠性和可用性。
                       使用者:生产模式提供了可靠的计算和存储服务,能够处理大规模数据和复杂计算

                                      任务,保证业务的连续性和稳定性。
                   c. 真实场景

                       开发者:在生产模式下,可以在真实数据和真实环境中验证和优化算法和模型,提

                                     升模型的准确性和适用性。
                       使用者:能够在实际业务场景中使用平台的功能,获得真实有效的计算结果,推动

                                      业务决策和发展。

2. 隐语部署资源要求及安装

        隐语在多系统方面的支持做的还挺不错,包括常见的linux系统、macOS系统,以及支持windows内置的WSL2 linux子系统。python的版本要求是3.8及以上,隐私计算行业公开的资料看,普遍厂商都将python升级到了3.10之后,一方面出于漏洞修复考虑,另一方面基于性能考虑。

        隐私计算一旦包含了tensorflow、pytorch等第三方包,一般docker镜像的大小会扩大到2-3G,业内厂商,比如蓝象提出一种空中安装的方式来提供安装服务,一开始可以是一个小的包,需要安装的全部服务的时候才会将所有的requirements都安装。因为你如果只是想要安全求交服务,完全没必要安装大且重的联邦学习模块的内容。类似富数等厂商,与隐语一样,可以提供lite的安装部署包,体积较小,适合轻量化部署。这种也是行业服务机构过程中衍生出来的共识。

        隐语提供了多种安装方式,包括docker镜像、pypi、源码等。一般来说,docker镜像部署是最一步到位和简单的,包含了运行应用所需的所有依赖和环境配置,无论是在开发、测试还是生产环境,使用 Docker 都能确保应用运行的一致性。这个也是业内目前看,最普遍采用的方案。

       

        其他诸如pypi安装、源码安装,更适合开发者用来研发和调试。不过只要下载docker镜像的速度能保证的基础上,个人还是更推荐使用docker的安装模式,简单方便。

3. 隐语使用初探

        

3.1   Ray基本概念

       隐语是基于 RayFed 实现,RayFed 是 Ray 框架的一个扩展,用于实现跨集群的分布式计算。因此,理解 Ray 的使用和分布式调度是理解隐语的关键。以下是如何从 Ray 的使用来理解隐语的使用和分布式调度的详细说明:

        Ray 任务:Ray 允许用户定义并行任务,这些任务可以在不同的节点上执行。每个任务都是一个独立的计算单元,可以由 Ray 调度器分配到集群中的任意节点。
        Actor 模式:Ray 中的 Actor 是一个有状态的计算单元,能够维护状态并处理消息。Actors 可以在不同节点之间通信,从而实现复杂的分布式应用。

        资源隔离:Ray 通过定义资源(如 CPU、内存等)来管理任务和 Actor 的资源分配。用户可以指定每个任务或 Actor 需要的资源,Ray 会根据资源情况调度这些任务。
        自动扩展:Ray 支持自动扩展,可以根据任务的负载动态增加或减少节点,以优化资源利用和任务执行效率。

        对象存储:Ray 提供了分布式对象存储(Plasma),允许任务之间共享数据。数据可以存储在内存中,提供高效的读写性能。
        任务依赖:Ray 允许用户定义任务之间的依赖关系,调度器会根据依赖关系自动安排任务的执行顺序。

3.2   基于ray来理解隐语的使用和分布式调度(个人的理解)

        隐语基于 RayFed 实现,RayFed 扩展了 Ray 的能力,使其能够支持跨集群的分布式计算。以下是如何理解隐语的使用和分布式调度:

        联邦学习任务:隐语支持跨多个集群的联邦学习任务。每个参与方可以在自己的集群中运行任务,RayFed 会负责调度这些任务并协调它们之间的通信。
        安全计算任务:隐语支持安全多方计算(MPC)任务,这些任务需要在多个参与方之间进行数据交换和计算。RayFed 提供了安全的通信通道,确保数据在传输过程中不被泄露。
        资源分配:隐语可以基于 Ray 的资源管理机制,为每个参与方分配合适的计算资源。用户可以指定每个参与方需要的资源,RayFed 会根据集群的资源情况进行调度。
        负载均衡:RayFed 能够根据任务的负载情况动态调整资源分配,确保计算任务能够高效执行。
        数据隔离与共享:在隐语中,不同参与方的数据是隔离的,但计算任务可以通过安全协议共享必要的数据。RayFed 利用 Ray 的对象存储和消息传递机制,确保数据在不同参与方之间安全传输和处理。
        数据依赖管理:隐语可以管理计算任务之间的数据依赖,确保任务按照正确的顺序执行。RayFed 会根据任务的依赖关系自动安排执行计划。

3.3 仿真模式

        单机仿真就是在自己当前本地,启动一个ray节点,来执行相应的计算任务。这个例子是在本地节点启动两个角色,alice和bob。执行的是PYU,也就是python的明文计算单元。

        

        

        集群仿真,是指部署两个节点,两台机器上部署,应该也可以支持在一台机器上,通过不同端口模拟两台机器,在第一台机器上部署ray的主节点,也就是ray head,指定ip、port、资源等信息,另一台则部署从节点,注意从节点的address这里写的是主节点的通信地址。服务启动完成后,执行python代码,address改成对应主节点的ip和端口。

        

        之前都是pyu的明文执行单元。现在创建spu的密态设备计算单元,在cluster集群配置信息,需要填写实际的alice和bob的通信地址,指定对应的mpc协议和整型碎片长度等一些必要的配置信息,这里选的是semi2k协议。然后初始化spu的集群信息。这种mpc启动模式在业内应该基本统一,没什么大的区别。从通信网络看,需要注意spu的端口,需要有别于ray的端口号。这里之所以采用不同的端口号,个人猜测是可能基于不同任务的功能分离或者安全性层面考虑,ray主要用于任务调度、资源管理和分布式计算。SPU 负责安全计算任务,如安全多方计算(MPC)等。SPU 的端口号用于安全计算任务的通信和数据交换。  

3.4 生产模式      

        注意生产模式的启动指令与仿真模式的差别,生产模式下,各个节点都是一个完整的ray集群,因此启动指令中都是ray start --head。

        生产模式下,多了self_party的参数设置,用于区分节点角色。init的address是self_party的ray head节点地址。

        spu的设置与仿真模式差别不大,注意区分端口号不要冲突,否则会带来网络通信相关的报错。说实话,端口号的管理也是一个累人的活。不过隐语提供了kuscia来解决。从生产模式的通信网络看:

  • Ray:负责分布式任务调度和资源管理,主要在集群内部节点之间进行通信。
  • Proxy:充当通信代理,确保不同计算节点之间的安全、可靠通信。
  • SPU:执行安全计算任务,确保涉及敏感信息的数据处理过程中的隐私和安全。

        另外也介绍了一下secretnote的使用,类似于notebook的编程体验。这个业内也有一些厂商提供该功能,隐语做了更多的用户体验的适配。

        分布式框架,业内普遍采用ray,可能也是一种共识。也许以后会有更优秀的框架取代ray,拭目以待。从隐语的设计来看,保持了对于使用其他可替代分布式框架的能力,架构还是蛮优秀的。

4. 实操体验

4.1 secretflow实操

采用docker镜像部署的模式,只需要拉取对应的docker镜像,运行即可。

为了模拟两个节点执行模式,需要启动两个镜像,如下所示:

单机模拟的场景,不需要执行ray启动命令,直接运行即可。

import secretflow as sf
 
sf.init(parties=['alice', 'bob'], address='local')
alice = sf.PYU('alice')
bob = sf.PYU('bob')
a = alice(lambda x : x + 1)(2)
print(a)
b = bob(lambda x : x + 1)(2)
print(b)

执行日志如下:

集群模拟,则需要在两个镜像中分别启动ray,alice节点执行head的启动,记录一下当前的ip地址。bob节点启动从节点,需要填写head节点的ip和端口。当然也可以采用docker指令docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'来查看镜像ip。

启动完成后,就可以执行相应的脚本了。依然选择在alice节点执行脚本,填写的address为主节点地址。

import secretflow as sf
 
sf.init(parties=['alice', 'bob'], address='172.17.0.2:8001')
alice = sf.PYU('alice')
bob = sf.PYU('bob')
a = alice(lambda x : x + 1)(2)
print(a)
b = bob(lambda x : x + 1)(2)
print(b)
print(sf.reveal(b))

执行日志如下:

spu的密态计算场景,也是类似,执行脚本如下:

import spu
import secretflow as sf
 
# Use ray head adress please.
sf.init(parties=['alice', 'bob'], address='172.17.0.2:8001')
 
cluster_def={
   
    'nodes': [
        {
   
            'party': 'alice',
            # Please choose an unused port.
            'address': 'ip:port of alice',
            'listen_addr': '172.17.0.2:9001'
        },
        {
   
            'party': 'bob',
            # Please choose an unused port.
            'address': 'ip:port of bob',
            'listen_addr': '172.17.0.3:9001'
        },
    ],
    'runtime_config': {
   
        'protocol': spu.spu_pb2.SEMI2K,
        'field': spu.spu_pb2.FM128,
        'sigmoid_mode': spu.spu_pb2.RuntimeConfig.SIGMOID_REAL,
    }
}
 
spu = sf.SPU(cluster_def=cluster_def)
print(spu)

需要注意,端口号与ray不同。

执行日志如下:

生产环境方法类似,只是每一个节点需要启动ray集群,需要注意带上head。

4.2 secretnote实操

我们采用的是将secretnote部署到服务器上,然后通过本地电脑的浏览器进行访问。

在服务器上使用 docker compose 启动两个容器,容器启动时会安装 SecretFLow、SecretNote,并且分别启动 Ray 服务以及 SecretNote 服务。

操作步骤如下:

mkdir snote
cd snote
vi docker-compose.yml

docker-compose.yml的内容

services:
  alice:
    image: 'docker.mirrors.sjtug.sjtu.edu.cn/secretflow/secretnote:1.5.0.dev'
    platform: linux/amd64
    environment:
      - SELF_PARTY=alice
      - ALL_PARTIES=alice,bob
    ports:
      - 8090:8888
    entrypoint: /root/scripts/start.sh
    volumes:
      - /root/scripts

  bob:
    image: 'docker.mirrors.sjtug.sjtu.edu.cn/secretflow/secretnote:1.5.0.dev'
    platform: linux/amd64
    environment:
      - SELF_PARTY=bob
      - ALL_PARTIES=alice,bob
    ports:
      - 8092:8888
    entrypoint: /root/scripts/start.sh
    volumes:
      - /root/scripts
docker compose up

启动后可以看到成功启动日志:

[+] Running 3/3
 ✔ Network snote_default    Created                                                                                                                                                                                                                0.1s 
 ✔ Container snote-alice-1  Created                                                                                                                                                                                                                0.5s 
 ✔ Container snote-bob-1    Created                                                                                                                                                                                                                0.5s 
Attaching to alice-1, bob-1
alice-1  | 2024-06-11 11:06:54,824	WARNING services.py:1832 -- WARNING: The object store is using /tmp instead of /dev/shm because /dev/shm has only 67108864 bytes available. This will harm performance! You may be able to free up space by deleting files in /dev/shm. If you are inside a Docker container, you can increase /dev/shm size by passing '--shm-size=5.09gb' to 'docker run' (or add it to the run_options list in a Ray cluster config). Make sure to set this to more than 30% of available RAM.
bob-1    | 2024-06-11 11:06:54,850	WARNING services.py:1832 -- WARNING: The object store is using /tmp instead of /dev/shm because /dev/shm has only 67108864 bytes available. This will harm performance! You may be able to free up space by deleting files in /dev/shm. If you are inside a Docker container, you can increase /dev/shm size by passing '--shm-size=5.09gb' to 'docker run' (or add it to the run_options list in a Ray cluster config). Make sure to set this to more than 30% of available RAM.
alice-1  | 2024-06-11 11:06:52,011	INFO usage_lib.py:381 -- Usage stats collection is disabled.
alice-1  | 2024-06-11 11:06:52,012	INFO scripts.py:722 -- Local node IP: 172.20.0.3
alice-1  | 2024-06-11 11:06:55,953	SUCC scripts.py:759 -- --------------------
alice-1  | 2024-06-11 11:06:55,954	SUCC scripts.py:760 -- Ray runtime started.
alice-1  | 2024-06-11 11:06:55,954	SUCC scripts.py:761 -- --------------------
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:763 -- Next steps
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:766 -- To add another node to this Ray cluster, run
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:769 --   ray start --address='172.20.0.3:6379'
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:778 -- To connect to this Ray cluster:
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:780 -- import ray
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:781 -- ray.init()
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:812 -- To terminate the Ray runtime, run
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:813 --   ray stop
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:816 -- To view the status of the cluster, use
alice-1  | 2024-06-11 11:06:55,954	INFO scripts.py:817 --   ray status
bob-1    | 2024-06-11 11:06:52,051	INFO usage_lib.py:381 -- Usage stats collection is disabled.
bob-1    | 2024-06-11 11:06:52,052	INFO scripts.py:722 -- Local node IP: 172.20.0.2
bob-1    | 2024-06-11 11:06:55,991	SUCC scripts.py:759 -- --------------------
bob-1    | 2024-06-11 11:06:55,991	SUCC scripts.py:760 -- Ray runtime started.
bob-1    | 2024-06-11 11:06:55,991	SUCC scripts.py:761 -- --------------------
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:763 -- Next steps
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:766 -- To add another node to this Ray cluster, run
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:769 --   ray start --address='172.20.0.2:6379'
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:778 -- To connect to this Ray cluster:
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:780 -- import ray
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:781 -- ray.init()
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:812 -- To terminate the Ray runtime, run
bob-1    | 2024-06-11 11:06:55,991	INFO scripts.py:813 --   ray stop
bob-1    | 2024-06-11 11:06:55,992	INFO scripts.py:816 -- To view the status of the cluster, use
bob-1    | 2024-06-11 11:06:55,992	INFO scripts.py:817 --   ray status
alice-1  | [W 2024-06-11 11:06:57.602 ServerApp] ServerApp.token config is deprecated in 2.0. Use IdentityProvider.token.
bob-1    | [W 2024-06-11 11:06:57.622 ServerApp] ServerApp.token config is deprecated in 2.0. Use IdentityProvider.token.
alice-1  | [I 2024-06-11 11:06:57.666 ServerApp] jupyter_lsp | extension was successfully linked.
alice-1  | [I 2024-06-11 11:06:57.666 ServerApp] jupyter_resource_usage | extension was successfully linked.
alice-1  | [I 2024-06-11 11:06:57.666 ServerApp] jupyter_server_proxy | extension was successfully linked.
alice-1  | [I 2024-06-11 11:06:57.675 ServerApp] jupyter_server_terminals | extension was successfully linked.
bob-1    | [I 2024-06-11 11:06:57.680 ServerApp] jupyter_lsp | extension was successfully linked.
bob-1    | [I 2024-06-11 11:06:57.681 ServerApp] jupyter_resource_usage | extension was successfully linked.
bob-1    | [I 2024-06-11 11:06:57.681 ServerApp] jupyter_server_proxy | extension was successfully linked.
alice-1  | [I 2024-06-11 11:06:57.682 ServerApp] secretnote.server | extension was successfully linked.
bob-1    | [I 2024-06-11 11:06:57.689 ServerApp] jupyter_server_terminals | extension was successfully linked.
alice-1  | [I 2024-06-11 11:06:57.695 ServerApp] Writing Jupyter server cookie secret to /root/.local/share/jupyter/runtime/jupyter_cookie_secret
bob-1    | [I 2024-06-11 11:06:57.696 ServerApp] secretnote.server | extension was successfully linked.
bob-1    | [I 2024-06-11 11:06:57.707 ServerApp] Writing Jupyter server cookie secret to /root/.local/share/jupyter/runtime/jupyter_cookie_secret
alice-1  | [W 2024-06-11 11:06:57.710 ServerApp] WARNING: The Jupyter server is listening on all IP addresses and not using encryption. This is not recommended.
alice-1  | [W 2024-06-11 11:06:57.710 ServerApp] WARNING: The Jupyter server is listening on all IP addresses and not using authentication. This is highly insecure and not recommended.
alice-1  | [I 2024-06-11 11:06:57.716 ServerApp] jupyter_lsp | extension was successfully loaded.
alice-1  | [I 2024-06-11 11:06:57.717 ServerApp] jupyter_resource_usage | extension was successfully loaded.
bob-1    | [W 2024-06-11 11:06:57.722 ServerApp] WARNING: The Jupyter server is listening on all IP addresses and not using encryption. This is not recommended.
bob-1    | [W 2024-06-11 11:06:57.722 ServerApp] WARNING: The Jupyter server is listening on all IP addresses and not using authentication. This is highly insecure and not recommended.
bob-1    | [I 2024-06-11 11:06:57.728 ServerApp] jupyter_lsp | extension was successfully loaded.
bob-1    | [I 2024-06-11 11:06:57.730 ServerApp] jupyter_resource_usage | extension was successfully loaded.
alice-1  | [I 2024-06-11 11:06:57.737 ServerApp] jupyter_server_proxy | extension was successfully loaded.
alice-1  | [I 2024-06-11 11:06:57.739 ServerApp] jupyter_server_terminals | extension was successfully loaded.
alice-1  | [I 2024-06-11 11:06:57.744 ServerApp] secretnote.server | extension was successfully loaded.
alice-1  | [I 2024-06-11 11:06:57.746 ServerApp] Serving notebooks from local directory: /root/workspace
alice-1  | [I 2024-06-11 11:06:57.746 ServerApp] Jupyter Server 2.13.0 is running at:
alice-1  | [I 2024-06-11 11:06:57.746 ServerApp] http://localhost:8888/secretnote/
alice-1  | [I 2024-06-11 11:06:57.746 ServerApp]     http://127.0.0.1:8888/secretnote/
alice-1  | [I 2024-06-11 11:06:57.746 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
bob-1    | [I 2024-06-11 11:06:57.750 ServerApp] jupyter_server_proxy | extension was successfully loaded.
bob-1    | [I 2024-06-11 11:06:57.752 ServerApp] jupyter_server_terminals | extension was successfully loaded.
bob-1    | [I 2024-06-11 11:06:57.757 ServerApp] secretnote.server | extension was successfully loaded.
bob-1    | [I 2024-06-11 11:06:57.758 ServerApp] Serving notebooks from local directory: /root/workspace
bob-1    | [I 2024-06-11 11:06:57.759 ServerApp] Jupyter Server 2.13.0 is running at:
bob-1    | [I 2024-06-11 11:06:57.759 ServerApp] http://localhost:8888/secretnote/
bob-1    | [I 2024-06-11 11:06:57.759 ServerApp]     http://127.0.0.1:8888/secretnote/
bob-1    | [I 2024-06-11 11:06:57.759 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

然后在本地电脑浏览器打开,打开地址需要注意一下,使用服务器的ip地址

http://服务器ip:8092/secretnote/secretflow

配置节点的时候注意使用服务器ip

使用的数据和脚本来自:secretnote/docs/guide/secretnote-sf.md at main · secretflow/secretnote · GitHub

其他代码不用动,直接执行全部,注意节点与数据文件对应关系,因为不对应会导致报错文件找不到的问题。对调一下节点名称就可以解决。

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
隐语框架与TEE(可信执行环境)的配合可以实现数据加密。隐语框架主要解决的是数据隐私保护和安全计算的问题,而TEE是一种安全的硬件或软件环境,可以提供可信的执行环境来保护数据和计算过程的安全性。通过将隐语框架与TEE结合,可以实现数据在计算过程中的加密和保护。 在隐语框架中,数据可以使用全密态计算或明密文混合计算的方式进行加密。全密态计算是一种在密文环境中进行计算的方式,数据在计算过程中一直保持加密状态,可以使用Secure Aggregation算法、MPC密态引擎、同态加密等技术来进行计算。而明密文混合计算则是将部分计算从密文环境搬到明文环境,在明文环境中进行计算可以提升计算的性能,同时通过安全退让来保证数据的安全性。 TEE提供了一个可信的执行环境,可以保护计算过程中的数据和代码安全。在隐语框架中,可以使用TEE来实现数据的加密和解密操作,以及进行安全计算。TEE可以提供硬件级的安全保护,例如Intel SGX和ARM TrustZone等,也可以通过软件模拟的方式提供安全执行环境。 通过隐语框架配合TEE实现数据加密,可以在保护数据隐私的前提下,进行安全的计算和数据交换。这种组合可以应用于各种场景,例如联邦学习、数据交易市场等,为数据安全和隐私保护提供了一种可行的解决方案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [隐私计算技术|深度解读可信隐私计算框架“隐语”](https://blog.csdn.net/m0_69580723/article/details/126662952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值