隐语 Unbalanced PSI Benchmark 白皮书

简介: 隐语 Unbalanced PSI Benchmark 白皮书

隐语 Unbalanced PSI Benchmark 白皮书

原创王细亮、张磊隐语的小剧场 2023-03-22 16:06 发表于浙江

收录于合集

#隐语解读20

#星河杯大赛专辑6

导语

去年10月份,隐语发布了PSI的性能数据,引起了内部和外部用户的广泛关注,具体协议包括:ecdh/kkrt16/bc22协议,这些协议更适合双方数据量差别不大的场景,称为平衡PSI(Balanced PSI)。隐私求交场景中,有时双方数据量级差异很大,例如:百万vs十亿,2千万vs 20亿。针对这种场景,隐语实现并开源了专门的非平衡PSI(Unbalanced PSI)协议,能得到更好的性能。具体来讲:与ecdh-psi对比,ecdh-psi在大数据集上进行两次加密操作。隐语实现的非平衡PSI只在大数据集上进行一次加密操作,在大数据集与小数据集的体量相差非常大的时候,总体计算量和运行时间大约是ecdh-psi的1/2。非平衡PSI还把协议分成离线和在线(offline/online)两个阶段,在提前执行离线(offline)缓存的情形下,在线阶段只需10多分钟即可完成在线(online)协议,得到交集结果。本文给出隐语非平衡PSI协议(Unbalanced PSI)的具体测试环境、步骤、和数据,供大家参考。备注:后续本文有增删订正内容,请参见留言区。

复现路径

一、测试机型

  • Python:3.8
  • pip: >= 19.3
  • OS: CentOS 7
  • CPU/Memory: 推荐最低配置是 8C16G
  • 硬盘:500G

二、安装conda

使用conda管理python环境,如果机器没有conda需要先安装。步骤如下:

#sudo apt-get install wget
wget
https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh


#安装
bash Miniconda3-latest-Linux-x86_64.sh

# 一直按回车然后输入yes
please answer 'yes' or 'no':
>>> yes

# 选择安装路径, 文件名前加点号表示隐藏文件
Miniconda3 will now be installed into this location:
>>> ~/.miniconda3

# 添加配置信息到 ~/.bashrc文件
Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no]
[no] >>> yes

#运行配置信息文件或重启电脑
source ~/.bashrc

#测试是否安装成功,有显示版本号表示安装成功
conda --version

三、安装secretflow






conda create -n sf-benchmark python=3.8
conda activate sf-benchmark
pip install -U secretflow

四、创建节点并启动集群

  • 创建ray header节点

创建ray header节点,选择一台机器为主机,在主机上执行如下命令,ip替换为主机的内网ip,命名为alice,端口选择一个空闲端口即可注意:192.168.0.1 ip为mock,请替换为实际的ip地址



RAY_DISABLE_REMOTE_CODE=true \ray start --head --node-ip-address="192.168.0.1" --port="9394" --resources='{"alice": 8}' --include-dashboard=False
  • 创建从属节点

创建从属节点,在bob机器执行如下命令,ip依然填alice机器的内网ip,命名为bob,端口不变



RAY_DISABLE_REMOTE_CODE=true \ray start --address="192.168.0.1:9394" --resources='{"bob": 8}'

五、数据要求Alice方:2000万Bob方:20亿交集:1000万

六、Benchmark脚本

脚本分为offline和online,offline用于对大数据方的setup、online对小数据的执行基于ecdh的oprf协议。参考阅读:非平衡隐私集合求交(Unbalanced PSI)协议介绍。

  • offline脚本:
import os
import sys
import time
import logging
import multiprocess
from absl import app
import spu
import secretflow as sf
#import random
# init log
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
# SPU settings
cluster_def = {
    'nodes': [
        # <<< !!! >>> replace <192.168.0.1:17268> to alice node's local ip & free port
        {'party': 'alice', 'id': 'local:0', 'address': f'192.168.0.1:17268'},
        # <<< !!! >>> replace <192.168.0.2:17269> to bob node's local ip & free port
        {'party': 'bob', 'id': 'local:1', 'address': f'192.168.0.2:17269'},
    ],
    'runtime_config': {
        'protocol': spu.spu_pb2.SEMI2K,
        'field': spu.spu_pb2.FM128,
    },
}
link_desc = {
    'recv_timeout_ms': 3600000,
}
def main(_):
    # sf init
    # <<< !!! >>> replace <192.168.0.1:9394> to your ray head
    sf.shutdown()
    sf.init(['alice','bob'],address='192.168.0.1:9394',log_to_driver=True,omp_num_threads=multiprocess.cpu_count())
    # init log
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
    alice = sf.PYU('alice')
    bob = sf.PYU('bob')
    #carol = sf.PYU('carol')
    # <<< !!! >>> replace path to real parties local file path.
    offline_input_path = {
        alice: 'dummyalice.csv',
        bob: '/root/benchmark/unbalanced_200000w.csv',
    }
    select_keys = {
        alice: ['id'],
        bob: ['id'],
    }
    spu = sf.SPU(cluster_def, link_desc)
    # offline 
    print("=====offline phase====")
    start = time.time()
    offline_output_path = {
        alice: "/data/unbalanced_2000w_out.csv",
        bob: "/data/unbalanced_200000w_out.csv",
    }
    offline_preprocess_path = "/root/benchmark/offline_out/offline_psi0107.csv"
    secret_key = "000102030405060708090a0b0c0d0e0ff0e0d0c0b0a090807060504030201000"
    secret_key_path = "/root/benchmark/secret_key.bin"
    with open(secret_key_path, 'wb') as f:
            f.write(bytes.fromhex(secret_key))
    reports = spu.psi_csv(
        key=select_keys,
        input_path=offline_input_path,
        output_path=offline_output_path,
        receiver='alice',  # if `broadcast_result=False`, only receiver can get output file.
        protocol='ECDH_OPRF_UB_PSI_2PC_OFFLINE',        # psi protocol
        precheck_input=False,  # will cost ext time if set True
        sort=True,  # will cost ext time if set True
        broadcast_result=False,  # will cost ext time if set True
        bucket_size=10000000,
        curve_type="CURVE_FOURQ",
        preprocess_path=offline_preprocess_path,
        ecdh_secret_key_path=secret_key_path,
    )
    #print(f"psi reports: {reports}")
    logging.info(f"offline psi reports: {reports}")
    logging.info(f"cost time: {time.time() - start}")
    sf.shutdown()
if __name__ == '__main__':
    app.run(main)

online脚本:

import os
import sys
import time
# import random
import logging
import multiprocess
from absl import app
import spu
import secretflow as sf
# init log
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
# SPU settings
cluster_def = {
    'nodes': [
        # <<< !!! >>> replace <192.168.0.1:13666> to alice node's local ip & free port
        {'party': 'alice', 'id': 'local:0', 'address': f'192.168.0.1:13666'},
        # <<< !!! >>> replace <192.168.0.2:12946> to bob node's local ip & free port
        {'party': 'bob', 'id': 'local:1', 'address': f'192.168.0.1:13667'},
    ],
    'runtime_config': {
        'protocol': spu.spu_pb2.SEMI2K,
        'field': spu.spu_pb2.FM128,
    },
}
link_desc = {
    'recv_timeout_ms': 3600000,
}
def main(_):
    # sf init
    # <<< !!! >>> replace <192.168.0.1:9394> to your ray head
    sf.shutdown()
    sf.init(['alice','bob'],address='192.168.0.1:9394',log_to_driver=True,omp_num_threads=multiprocess.cpu_count())
    # init log
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
    alice = sf.PYU('alice')
    bob = sf.PYU('bob')
    # <<< !!! >>> replace path to real parties local file path.
    online_input_path = {
        alice: '/root/benchmark/unbalanced_2000w.csv',
        bob: 'dummy.bob.csv',
    }
    output_path = {
        alice: '/data/unbalanced_20000wvs2000w.csv',
        bob: '/data/unbalanced_20000wvs2000w.csv',
    }
    select_keys = {
        alice: ['id'],
        bob: ['id'],
    }
    spu = sf.SPU(cluster_def, link_desc)
    offline_preprocess_path = "/root/benchmark/offline_out/offline_psi0107.csv"
    secret_key_path = "/root/benchmark/secret_key.bin"
    # online 
    print("=====online phase====")
    start = time.time()
    reports = spu.psi_csv(
        key=select_keys,
        input_path=online_input_path,
        output_path=output_path,
        receiver='alice',  # if `broadcast_result=False`, only receiver can get output file.
        protocol='ECDH_OPRF_UB_PSI_2PC_ONLINE', # psi protocol
        precheck_input=True,  # will cost ext time if set True
        sort=True,  # will cost ext time if set True
        broadcast_result=False,  # will cost ext time if set True
        bucket_size=100000000,
        curve_type="CURVE_FOURQ",
        preprocess_path=offline_preprocess_path,
        ecdh_secret_key_path=secret_key_path,
    )
    #print(f"psi reports: {reports}")
    logging.info(f"online psi reports: {reports}")
    logging.info(f"cost time: {time.time() - start}")
    sf.shutdown()
if __name__ == '__main__':
    app.run(main)
  • Benchmark报告

备注:目前是小数据方到大数据方的交集结果,如果大数据方到小数据方的交集结果online运行时间会增加一倍 。

解读:• Unbalanced PSI的offline阶段,大数据方对大数据集(20亿)进行加密并发送(截取12B)到小数据方,加密(ecc点乘)可以进行并发计算,CPU的核数增大可以提高性能。可以看到性能数据基本和CPU的核数成线性关系,网络带宽消耗不大。• Unbalanced PSI的online阶段,可以划分为两部分子阶段,对小数据集数据执行ecdh-oprf得到小数据集的加密结果;小数据集加密结果和offline阶段的到大数据集加密数据进行比较的到交集。总体计算量和传输量不大,运行时间在10几分钟左右。

  • Balanced PSI Benchmark报告

为了方便大家对比,同等硬件资源和数据规模下,对平衡PSI做了性能测试,报告如下:

解读:

Balanced PSI 跑20亿*2000万规模数据时,在8C16G资源下CPU成为瓶颈,机器资源提升到64C128G后LAN 环境 79分钟完成任务执行。


参考文章:1.非平衡隐私集合求交(Unbalanced PSI)协议介绍2.隐语 balanced psi Benchmark 白皮书

相关文章
|
数据采集 缓存 安全
隐语小课|非平衡隐私集合求交(Unbalanced PSI)协议介绍
隐语小课|非平衡隐私集合求交(Unbalanced PSI)协议介绍
1859 0
|
Ubuntu 调度 Docker
2024.3.21隐语训练营第4讲笔记:SecretFlow & SecretNote安装部署
本文介绍了SecretFlow和SecretNote的安装和部署
1137 3
|
运维 监控 算法
稳定性保障6步走:高可用系统大促作战指南!
年年有大促,大家对于大促稳定性保障这个词都不陌生,业务场景尽管各不相同,“套路”往往殊路同归,全链路压测、容量评估、限流、紧急预案等,来来去去总少不了那么几板斧。跳出这些“套路”,回到问题的本质,我们为什么要按照这些策略来做?除了口口相传的历史经验,我们还能做些什么?又有什么理论依据?
稳定性保障6步走:高可用系统大促作战指南!
|
5月前
|
人工智能 搜索推荐 机器人
OpenClaw能做什么?2026年轻量服务器部署OpenClaw(Clawdbot)保姆级指南
OpenClaw(原Clawdbot)作为一款开源个人AI助手与自主代理工具,核心价值在于打破AI工具的使用壁垒,让AI从“只能聊天”升级为“能办实事”,无需专业技术背景,即可通过日常消息应用调用强大的自动化能力。与传统聊天机器人不同,OpenClaw拥有“双眼和双手”——可读写文件、运行终端命令、浏览网页、对接外部API,还具备长期记忆功能,能记住用户偏好与习惯,真正成为融入日常工作生活的智能队友。
1147 2
|
10月前
|
缓存 PyTorch API
TensorRT-LLM 推理服务实战指南
`trtllm-serve` 是 TensorRT-LLM 官方推理服务工具,支持一键部署兼容 OpenAI API 的生产级服务,提供模型查询、文本与对话补全等接口,并兼容多模态及分布式部署,助力高效推理。
1215 155
|
存储 人工智能 API
AI代理性能提升实战:LangChain+LangGraph内存管理与上下文优化完整指南
在AI代理系统开发中,上下文工程成为提升系统性能的关键技术。本文探讨了从提示工程到上下文工程的转变,强调其通过为AI系统提供背景信息和工具支持,显著提升智能化程度和实用价值。文章系统分析了上下文工程的理论基础、核心策略(如写入、选择、压缩和隔离),并结合LangChain和LangGraph工具,展示了如何实现上下文工程技术以优化AI代理性能。通过Scratchpad机制、内存管理、RAG系统集成、多代理架构及沙盒环境等技术手段,开发者可以更高效地构建高性能、可扩展的AI系统。
1625 0
AI代理性能提升实战:LangChain+LangGraph内存管理与上下文优化完整指南
|
XML JSON API
如何在 Postman 中上传文件和 JSON 数据
如果你想在 Postman 中同时上传文件和 JSON 数据,本文将带你一步一步地了解整个过程,包括最佳实践和技巧,让你的工作更轻松。
|
算法 安全 大数据
隐私计算实训营第5讲-------隐私求交和隐语PSI介绍以及开发实践
隐私求交(Private Set Intersection, PSI)是利用密码学技术在不暴露数据集以外信息的情况下找到两集合的交集。隐语SPU支持三种PSI算法:ECDH(适合小数据集)、KKRT(基于Cuckoo Hashing和OT Extension,适合大数据集)和BC22PCG(使用伪随机相关生成器)。ECDH基于椭圆曲线 Diffie-Hellman,KKRT利用OT Extension实现高效处理,而BC22PCG通过压缩满足特定相关性的随机数减少通信量。此外,还有基于Oblivious Pseudo-Random Function (OPRF)的PSI协议。
2114 0
|
机器学习/深度学习 测试技术 API
QwQ-32B开源!更小尺寸,仅1/20参数性能比肩满血R1
今天,通义千问开源了推理模型QwQ-32B
1135 17
|
Ubuntu Linux Docker
课4-隐语SecretFlow、SecretNote安装部署
SecretFlow是支持Python 3.8及以上版本的隐私计算框架,兼容CentOS 7、Anolis8、Ubuntu 18.04等等。它提供两种安装包:所有需求的大体积`secretflow`和仅含基础功能的小体积`secretflow-lite`。用户可通过Docker、pip或源码安装。安装后,可使用Docker镜像在本地部署,并通过Ray进行集群仿真。更多详细信息和部署指南可在官方手册中找到。此外,SecretFlow还提供了类似Jupyter Notebook的SecretNote工具,实现多节点代码自动执行和跟踪。