本期隐语社区问答,共收集22条精选issues。其中安装部署问答13条,功能性问答6条,其他相关问答3条,供大家参考阅读。另外,小伙伴们在使用过程中遇到任何问题,都可以上github隐语主页进行提问和交流,隐语技术同学会给出相关建议和解决方法,欢迎访问👏:https://github.com/secretflow/secretflow
同时欢迎小伙伴们加入隐语SecretFlow交流群,扫描下方二维码或通过微信号:SecretFlow01,添加隐语小助手好友,即可私聊申请入群。
本群主要为大家提供交流讨论隐语及隐私计算技术的平台,在这里你可以与专家互动、与同好交流,还可以获取隐语官方最新资讯。
安装部署问题
问题1:
集群模式中的ip和端口的含义
我有这么几个理解,不确定是否正确,求指教。
- ip_1 和 port_1 初始化了 ray 的 master,然后 ip_2 加入了 ip_1 声明的这个集群。
- ip_3 以及 ip_4 是声明的两个 secretflow 的节点,与 ip_1 和 ip_2 并不是强绑定关系(虽然一般情况下都是一致的)。port_3 和 port_4 是声明的两个 secretflow 节点间的通信端口,必须与 port_1 不同,同时还需要与 ray 的通信端口 8881 不同。
- ip_5 和 port_5 指明 secretflow 去连接 ray 的集群,所以 ip_5 和 port_5 是与 ip_1 和 port_1 一致的。
解答:是的,你的理解是对的,解释的非常清楚。一点点小的改进:同时还需要与 ray 的通信端口 8881 不同,其实本质上是使用未被占用的端口以免端口冲突。
问题2:安装失败,spu找不到#pip install -U secretflow
...
ERROR: Could not find a version that satisfies the requirement spu==0.1.0b1 (from secretflow) (from versions: none)
ERROR: No matching distribution found for spu==0.1.0b1 (from secretflow)解答:试试用docker镜像,镜像已经安装好了secretflowsecretflow/secretflow-anolis8:0.6.13b1最新的镜像版本可以访问https://hub.docker.com/r/secretflow/secretflow-anolis8/tags
问题3:1.在本地两台虚拟机上运行了一个Ray集群:启动命令:头节点:ray start --head --node-ip-address="192.168.14.132" --port="6379" --resources='{"alice": 4}' --include-dashboard=False --disable-usage-stats (ray) [root@localhost ~]# lsof -i:6379工作节点:ray start --address='192.168.14.132:6379' --resources='{"bob": 4}' --disable-usage-stats2.在头节点的Python编译器中>>> import secretflow as sf>>> sf.init(address='192.168.14.132:6379')出现报错:RuntimeError: b'GCS has started but no raylets have registered yet.'3.求教如何进行下去解答:试试:
- 先停掉已有的集群(执行ray stop),然后执行ray start --head(注意不带其他参数),启动之后,再执行sf.init看下是否成功。-> 如果这个方式没问题,至少证明你的机器上可以运行ray。那么可能要检查下node-ip-address是否有问题,比如先换成127.0.0.1再试试。
- 尝试在/tmp/ray/session_xxx/logs/目录下,看下gcs.out、raylet.out等日志里是否有有用的信息。xxx应该和你启动ray的时间匹配。
- 另外,启动成功之后,也可以检查下raylet进程是否存活,ps -ef | grep raylet
问题4:SecretFlow能否源码编译安装?解答:可以的1.您可以尝试以下方法:
切换到 secretflow 代码根目录,执行:pip install -e .
要求 Python 环境为 3.8
2.补充一下,应该还需要先自己编译 spu 和 heu
两个 repo 的 readme 里都有对应的编译方法
问题5:集群模式使用公网EIP问题问题描述:环境:准备了两台云服务器,各自有独立的公网eip,分别作为head和work节点。启动命令如下:ray start --head --node-ip-address="head公网ip" --port="32345" --redis-password='1234' --resources='{"alice": 8}' --include-dashboard=False --disable-usage-stats ray start --address="head节点公网ip:32345" --node-ip-address="work节点公网ip" --redis-password='1234' --resources='{"bob": 8}' --disable-usage-stats执行横向dataframe求平均是出错:RuntimeError: what: [external/yasl/yasl/link/transport/channel_brpc.cc:121] brpc server failed start如果替换为云服务器各自的内外ip,能够顺利执行。复现代码如下:
import secretflow as sf import time import spu sf.shutdown() # 初始化serectflow,集群模式,设置集群head节点地址 password='1234' sf.init(address='head节点公网ip:32345', _redis_password=password) # 定义两方计算集群,用于构建两方计算密文设备 cdef = { 'nodes': [ {'party': 'alice', 'id': 'local:0', 'address': 'head节点公网ip:30345'}, {'party': 'bob', 'id': 'local:1', 'address': 'work节点公网ip:30345'}, ], 'runtime_config': { 'protocol': spu.spu_pb2.SEMI2K, 'field': spu.spu_pb2.FM128, 'sigmoid_mode': spu.spu_pb2.RuntimeConfig.SIGMOID_REAL, }, } # 两参与方,明文设备 alice, bob= sf.PYU('alice'), sf.PYU('bob') # 构建两方计算密文设备 spu_2pc = sf.SPU(cdef) print(spu_2pc) from secretflow.data.horizontal import read_csv as h_read_csv from secretflow.security.aggregation import SecureAggregator from secretflow.security.compare import SPUComparator # 安全聚合 comp = SPUComparator(spu_2pc) aggr = sf.security.aggregation.SPUAggregator(spu_2pc) print(aggr) #定义数据集路径 h_alice_path="/root/secretflow/demo/dataset/wages1.csv" h_bob_path="/root/secretflow/demo/dataset/wages2.csv" # 读取两方数据为横向dataframe t0 = time.time() hdf = h_read_csv({alice: h_alice_path, bob: h_bob_path}, aggregator=aggr, comparator=comp) t0_e = time.time() print("h_read_csv time cost:\n", float(t0_e-t0)*1000.0, "ms") print(sf.reveal(hdf)) t1 = time.time() print('Horizontal df:\n', hdf.mean(numeric_only=True)) t1_e = time.time() print("hdf.mean time cost:\n", float(t1_e-t1)*1000.0, "ms")
解答:公网EIP并不属于机器的ip,所以监听EIP地址会失败。正确方式是在配置SPU的时候,配置listen_address(比如可以是0.0.0.0:port)另外,从我们使用brpc的经验来看,brpc server failed start的几种常见可能性是1)监听地址无法解析2)端口已经被占用3)监听地址不正确
问题6:m1 Mac安装最新版secretflow出错解答:m1 用 conda 装 grpcio。M1 还属于早期实验性支持,发现问题欢迎反馈。
问题7:spu的clusterdef修改为多机ip时无法运行基于secretflow-beta\docs\tutorial\PSI_On_SPU.py1.首先将192.168.207.193和192.168.207.194组成ray集群2.修改testing文件,将spu传入的clusterdef的'alice'和'bob'地址分别设置为(1)192.168.207.193+端口,(2)192.168.207.194+端口3.运行psi_csv报错解答:看上去似乎端口已经被占用了,所以导致spu创建失败。
问题8:数据分布在多方时,该如何使用input_path = {alice: '.data/alice.csv', bob: '.data/bob.csv'}output_path = {alice: '.data/alice_psi.csv', bob: '.data/bob_psi.csv'}spu.psi_csv('uid', input_path, output_path)解答:以input_path = {alice: '.data/alice.csv', bob: '.data/bob.csv'}为例,这行代码表示alice读取alice本地的data/alice.csv文件,bob读取bob本地的data/bob.csv。所以只需要集群化启动secretflow集群,读取的就是参与方各自的文件了。
集群化参考Cluster Modehttps://secretflow.readthedocs.io/en/latest/getting_started/deployment.html#cluster-mode
问题9:在做PSI时,如果一方运行,另一方不运行。在尝试连接超时时会出现段错误
解答:是的,这是预期行为。如果直接使用 SPU,我们确实要求我们的用户在短时间内运行双方。你可以尝试在 Secretflow 中调用 PSI,这将有助于同时向双方发送 MPI PSI 代码。
问题10:使用Cluster Mode,出现Unable to connect to GCS at 192.168.11.129:7000解答:在本方可以通过上述地址请求到对侧服务器吗?(尝试使用ping和curl检测链路连通性) 同时在云服务器上可通过netstat查看端口监听状态。同时可检查云服务器防火墙是否禁止了上述开启的端口从外部访问。
问题11:请问secretflow-ray这个有源码吗?解答:我们对ray做了一些安全上的改进,但是功能上和开源ray是一致的,这一块的工作还在持续进行中,我们会在完善之后开源出来。
问题12:安装 sf-heu 时出错报错信息:/heu/docs$ pip install sf-heuDefaulting to user installation because normal site-packages is not writeableERROR: Could not find a version that satisfies the requirement sf-heu (from versions: none)ERROR: No matching distribution found for sf-heuos/python/pip版本信息:Pop!_OS 22.04 LTS
Python 3.10.4
pip 22.0.2解答:我们现在只为 Python 3.8 提供预制wheel包。有两种选择:1. 按照构建说明构建您自己的wheel包。2.使用Secretflow的docker镜像。
问题13:centos7.6 使用bazel build 报错报错信息:ERROR:/root/.cache/bazel/_bazel_root/9de4a6aef89daf40df580afb13ff9f9d/external/com_github_intel_ipp/BUILD.bazel:10:20: Foreign Cc - CMake: Building ipp failed: (Exit 1): bash failed: error executing command /bin/bash -c bazel-out/k8-opt/bin/external/com_github_intel_ipp/ipp_foreign_cc/wrapper_build_script.shgcc11是自己编译安装的,centos7.6默认是gcc 4.8.5解答:centos 7 rh的gcc11包
yum install -y centos-release-scl
yum install -y devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-binutils
应该就可以装上,然后
source scl_source enable devtoolset-11
功能性问题
问题1:ml的前端是只能用纯jax写么?多方机器学习中,spu中的fit是否可使用sklearndef fit(*train):C = 0.8gamma = 20decision_function_shape = 'ovo'x, y = split_x_y(train)clf = svm.SVC(C=C, kernel='linear', gamma=gamma, decision_function_shape=decision_function_shape)clf.fit(x, y.ravel())return clf.coef_, clf.intercept_解答:对于纯密态计算的方案,目前原生 AI 框架对接当前推荐的是 Jax,理论上所有可以翻译到 XLA IR 的框架都可以被 SPU 对接上,因此后续会包含 TF & Torch,可以看下
https://spu.readthedocs.io/en/beta/getting_started/introduction.html。
走 XLA 的好处是未来 torch/jax/tf 自身的迭代和隐语的迭代是解耦的,可以用上最新版本的原生 AI 框架。回到 SKLearn,SKLearn 本身并不能直接翻译到 XLA,所以暂时这么做是不可以的。但是我们确实有计划提供类 SKLearn 的 API 风格的安全机器学习算法,这样可以减少用户的学习成本。
问题2:请问两方能使用ABY3协议么解答:不能,对于ABY3协议来说,如果两方共谋将会得到全部数据信息。按照你的假设,假设两方分别为alice和bob,alice承担了p1和p2, bob承担了p3, 那么实际上alice可以reveal所有密文,对于bob来说是不可接受的。
问题3:secretflow支持多方(大于三方)PSI和机器学习建模吗解答:secretflow支持多种算法,包括:(1)MPC(可证安全)的建模:目前支持了三方/多方LR,稍晚些时候会支持三方/多方XGB (2)PSI:目前主要是两方的PSI,预计在今年11月份支持多方PSI(3)联邦学习(非可证安全)的建模:目前已经支持水平多方XGB,稍晚些会发布水平LR算法,另外还有一些NN算法,部分已经支持,原则上也是可以多方参与的
问题3:多方计算每次都需要sf.shutdown()+sf.init()么解答:在一个python解释器中,其实只需要sf.init一次,后台会启动计算集群,然后可以往该集群提交运行多个task,这个没有限制,shutdown其实会在进程退出时自动调用,所以也可以不显示手动调用的。教程里的文档加上shutdown是为了避免有人在jupyter notebook打开之后,重复跑sf.init()导致报错。
问题4:请问有使用cheetah的代码demo吗?解答:隐语并没有使用cheetach的demo,当前spu device支持多种密态协议,你只需要在init spu device的时候在runtime config中选择cheetah协议即可。
问题5:SFXgboost目前只能train,不能evaluate/predict吗解答:SFXgboost暂时只支持train,产出的model可以save下来,这个model可以用标准原生xgboost来进行加载预测,评估等。后续版本会增加联邦评估和预测的能力
问题6:请问平台里的sql功能是基于MPC的安全版本还是执行原生的sql语句?解答:
用户输入的sql经过parser后会被拆分成多个子sql,对于只涉及单方数据的子sql会发到本地sql引擎明文执行,只有涉及到多方数据的子sql才会进入密态进行mpc计算。隐语的sql是一个典型的可证安全的明密文混合计算
其他问题
问题1:DataFrame是否可以从hdfs中聚合数据?解答:目前read_csv底层是调用pandas.read_csv, pandas.read_csv并不支持hdfs,只能从csv文件加载。
问题2:我想请教一个如何用编程实现的问题,我看secretflow的教程是单机模拟,就可以在单机的一个.py程序中编程实现。那如果是分布式的,一个物理节点提供标签,一个物理节点提供数据,再来一个物理节点提供模型,那么在哪个节点进行编程实现,这一个节点如何访问其他节点的变量?# load features on AliceX, _ = ppd.device("P1")(load_dataset)()# load labels on Bob_, Y = ppd.device("P2")(load_dataset)()比如,X,Y分别在不同的节点中,如何把它们一块放如损失函数中。解答:首先,隐语提供的是single controller编程模式,站在全局视角编写代码。隐语编程并不区分单机或集群模式,其写法是通用的。(单机模式也是通过多进程模拟的多方)具体到你的问题,Alice有特征,Bob有标签。如果你想进行计算,需要想清楚计算模型是什么(比如执行什么算法),以及如何保证安全性。
按照你的问题假设,如果你想让Bob计算loss,则可以把X发送给Bob,但是注意这是不安全的,X将会被明文发送给Bob。所以你需要设计算法模型来保证安全。# 以下代码是不安全的明文计算,请不要这么写alice, bob =sf.PYU('alice'), sf.PYU('bob')x =alice(load_feature)()y =bob(load_label)()# 基于x和y计算loss# x.to(bob) 表示将x传输给bob,注意是明文发送bob(loss_func)(x.to(bob), y)比如想进行逻辑回归计算,则可以参考Logistic Regression with SPU — SecretFlow documentation。另外也可以阅读水平联邦等教程
问题3:使用猎豹协议测试2方的万次比较,需要花将近7s的时间,正常吗?解答:猎豹是一个纯两方的协议,计算过程中涉及到下层 OT/HE 的计算,速度比ABY3这类协议会慢许多。