首页 > 编程语言 >隐语实训09-SML入门基于SPU迁移机器学习算法实践

隐语实训09-SML入门基于SPU迁移机器学习算法实践

时间:2024-07-01 18:32:03浏览次数:13  
标签:jnp jax 09 alice SPU SML 127 spu sim

一、32位浮点数

32位浮点数(Single Precision Floating Point)是一种用于表示实数的标准格式,由IEEE 754标准定义。

表示方法

32位浮点数由三部分组成:

  1. 符号位(S):1位,表示数值的正负。
  2. 指数位(E):8位,用于表示数值的范围。
  3. 尾数位(M):23位,表示有效数字。

其表示公式为:

( − 1 ) S × 1. M × 2 ( E − 127 ) ( − 1 ) S × 1. M × 2 ( E − 127 ) ( − 1 ) S × 1. M × 2 ( E − 127 ) (−1)S×1.M×2(E−127)(-1)^S \times 1.M \times 2^{(E-127)}(−1)S×1.M×2(E−127) (−1)S×1.M×2(E−127)(−1)S×1.M×2(E−127)(−1)S×1.M×2(E−127)

  • 符号位 S 决定数的正负,0表示正数,1表示负数。
  • 指数位 E 采用偏移量为127的表示方法,即实际指数为 E−127。
  • 尾数位 M 代表小数部分,实际有效数字为 1.M。

优缺点

优点

  • 范围广:可以表示非常大的数和非常小的数。
  • 精度高:对大多数应用场景下的计算精度需求都能满足。

缺点

  • 计算复杂:浮点运算相对耗时,硬件实现复杂。
  • 存储空间大:占用32位存储空间。

应用场景

32位浮点数广泛用于科学计算、图形处理、机器学习等需要高精度和大范围数值表示的领域。

二、8位定点数

8位定点数(Fixed Point)是一种用于表示小范围数值的表示方法,适用于嵌入式系统和资源受限的环境。

表示方法

8位定点数的表示方法有多种,常见的是 Q7 格式,即:

  • 符号位(S):1位,表示数值的正负。
  • 整数位:0位。
  • 小数位:7位,表示小数部分。

其表示公式为:

( − 1 ) S × ( M 27 ) ( − 1 ) S × ( M 2 7 ) ( − 1 ) S × ( 27 M ) (−1)S×(M27)(-1)^S \times \left(\frac{M}{2^7}\right)(−1)S×(27M) (−1)S×(M27)(−1)S×(27M​)(−1)S×(27M)

  • 符号位 S 决定数的正负,0表示正数,1表示负数。
  • 尾数位 M 直接表示小数部分。

优缺点

优点

  • 计算简单:定点数运算简单,硬件实现高效。
  • 存储空间小:仅占用8位存储空间,节省内存。

缺点

  • 范围有限:只能表示较小范围的数值。
  • 精度有限:小数位越多,能表示的范围越小。

应用场景

8位定点数常用于嵌入式系统、DSP(数字信号处理)和物联网设备中,这些场景对计算资源和存储空间要求严格,且数值范围和精度需求较低。

三、比较与选择

精度与范围

  • 32位浮点数:适用于需要高精度和大范围数值的应用场景,如科学计算和机器学习。
  • 8位定点数:适用于资源受限且数值范围和精度要求较低的场景,如嵌入式系统和简单的信号处理。

计算复杂性

  • 32位浮点数:计算复杂,硬件实现成本高。
  • 8位定点数:计算简单,硬件实现成本低。

存储需求

  • 32位浮点数:占用32位存储空间。
  • 8位定点数:占用8位存储空间,更节省内存。

实际应用

  • 32位浮点数:广泛用于需要高精度和广泛范围的领域,如科学计算、图形处理、机器学习等。
  • 8位定点数:广泛用于嵌入式系统、物联网设备和DSP等资源受限的领域。

四、SML实践

接下来实践一个代码,来展示如何使用 SecretFlow 库和 SPU(Secure Processing Unit)设备来执行隐私保护的计算任务。代码涵盖了网络配置、数学运算的模拟、数据加载和处理、以及网络模拟操作等多个方面。模拟网络条件变化前后对计算任务性能的影响

import secretflow as sf
import spu
import os
import numpy as np
import jax.numpy as jnp
import jax
import jax.lax
import spu.utils.simulation as spsim
import spu.spu_pb2 as spu_pb2
from functools import partial

network_conf ={
    "parties":{
        "alice":{
            "address":"alice:8000",
        },
        "bob":{
            "address":"bob:8000",
        },
    },
}


party = os.getenv("SELF_PARTY","alice")
sf.shutdown()
sf.init(
    address="127.0.0.1:6379",
    cluster_config={**network_conf,"self_party": party},
    log_to_driver=True,
)

!yum install -y iproute-tc

#we know that dk is wrong when |x| is very small
# Let us try it.(we only show part here.)
# define some test function and data used in simulation
#def test_square_and_sum_when_x_small(x):
#    return jnp.sum(jnp.square(x))

def compute_dk_func(x, eps=1e-6, iterations=100):
    result = x
    for _ in range(iterations):
        result = jnp.square(result)
        result = jax.lax.rsqrt(jnp.sum(result) + eps)
    return result
    
x = np.array([1e-5]* 10)

#First,we run SPU with simulator
#Indeed,simulation can be run within single node.
# a.run with CHEETAH
sim_che = spsim.Simulator.simple(2, spu_pb2.ProtocolKind.CHEETAH, spu_pb2.FieldType. FM64)
spsim.sim_jax(sim_che, test_square_and_sum_when_x_small)(x)

#b.run with ABY3
# this time,we alse print some profile stats.
config_aby = spu.RuntimeConfig(
    protocol=spu_pb2.ProtocolKind.ABY3,
    field=spu.FieldType.FM64,
    fxp_fraction_bits=18,
    enable_hal_profile=True,
    enable_pphlo_profile=True,
)
sim_aby=spsim.Simulator(3,config_aby)
print(spsim.sim_jax(sim_aby, test_square_and_sum_when_x_small)(x))

!tc qdisc del dev eth0 root


!ping -c 4 bob

!ping -c 4 alice

# Emulation should be run from source in SPU, so we use Secretflow here to do the efficiency experiments.
# You can use the similar trick for emulation directly in SPU.
def compute_dk_func(x,eps=1e-6):
    return jax.lax.rsqrt(jnp.sum(jnp.square(x))+ eps)

x = np.random.rand(1_000_000)


# SPU settings
cluster_def={
    'nodes':[
        {'party':'alice','id':'local:0','address': 'alice'+ ':12945'},
        {'party':'bob','id':'local:1','address':'bob'+':12945'},
    ],
    'runtime_config':{
        #SEMI2K support 2/3 PC,ABY3 only support 3PC, CHEETAH only support 2PC.
        # pls pay attention to size of nodes above, nodes size need match to Pc setting.
        'protocol':spu.spu_pb2.SEMI2K,
        'field':spu.spu_pb2.FM64
    },
}
alice_device = sf.PYU("alice")
bob_device = sf.PYU("bob")
spu_device =sf.SPU(cluster_def)

#first, load data to PYU
alice_data = alice_device(lambda x: x)(x)

#SPU may need some init, so we run this twice...
ret  = spu_device(compute_dk_func)(alice_data)
sf.reveal(ret);

#调整网络状况,限制带宽和延迟
!tc qdisc add dev eth0 root handle 1: tbf rate 100mbit burst 128kb limit 10000
!tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 10msec limit 8000

!ping -c 4 bob

!ping -c 4 alice
#调整网络状况后再执行计算任务,此次任务执行时间应该变长了
ret = spu_device(compute_dk_func)(alice_data)
sf.reveal(ret);

!tc qdisc del dev eth0 root


接下来作一个jax.numpy.digitize 的MPC-friendly的实现,原课程的案例如下:

x=np.array([0.0, 0.2, 6.4, 3.0, 1.6, 12.0])
bins =np.array([0.0, 1.0, 2.5, 4.0, 10.0])
jnp.digitize(x,bins)


config_aby = spu.RuntimeConfig(
    protocol=spu_pb2.ProtocolKind.ABY3,
    field=spu.FieldType.FM64,
    fxp_fraction_bits=18,
    enable_hal_profile=True,
    enable_pphlo_profile=True,
)
sim_aby=spsim.Simulator(3,config_aby)
print(spsim.sim_jax(sim_aby, jnp.digitize)(x,bins))

# MPC-friendly jnp.digitize example
# Note: here,we only deal the case of `right=False', other cases are similar.
def my_digitize(x, bins):
    # vectorize
    com=x.reshape(*x.shape, -1)>= bins
    #count the number ofxthat exceeds bins
    return jnp.sum(com, axis=1)
print(spsim.sim_jax(sim_aby,my_digitize)(x,bins))

在这里插入图片描述

在原案例中的实现在每次迭代中都对整个数组进行平方和开方操作,这可能导致不必要的计算负担。现在使用广播和累计求和直接计算看下效果

def optimized_digitize(x, bins):
    # 使用广播和累积求和直接计算
    return jnp.sum(x[:, None] >= bins, axis=-1)
print(spsim.sim_jax(sim_aby,optimized_digitize)(x,bins))

任务时间上快了一些,通信没什么变化,还是有一定效果的

在这里插入图片描述

标签:jnp,jax,09,alice,SPU,SML,127,spu,sim
From: https://blog.csdn.net/sunxi1900/article/details/140088102

相关文章

  • (参数)AFE58JD32LPZAV超声波 AFE、模数转换器ADC09SJ800AAV 800MSPS ADC、ADS52J65IRGC
    1、AFE58JD32LPZAV是一款具有18.5mW/通道功率、数字解调器以及JESD204B和LVDS接口的32通道超声波AFE。AFE58JD32LP是高度集成的模拟前端(AFE)解决方案,专用于需要高性能、低功耗和小尺寸特性的便携式超声波系统。规格位数:10,12通道数:32功率(W):18.5mW电压-供电,模拟......
  • k8s-09-Deployment
    Deployment微服务化:将一个大规模系统拆分成各个独立运行的组件更新pod:直接删除所有现有的pod,然后创建新的pod。先创建新的pod,并等待它们成功运行之后,再删除旧的pod。按顺序创建新的pod,然后逐渐删除旧的pod。第1种会导致应用程序在一定的时间内不可......
  • BK8090 单芯片2.4GHz RF片上系统(SoC),上海博通非标2.4G新系列
    BK8090是一款单芯片2.4GHz射频片上系统(SoC),用于低功耗无线应用。BK8090结合了高性能2.4GHz射频收发器和增强型8051兼容MCU的优点,容量为2KBRAM和8kb的OTP内存和基本外设。采用先进的设计技术和超低功耗的工艺技术,BK8090提供高集成度和为目标应用(如USB加密狗、鼠标设备、键......
  • [题解]CF1092D1 Great Vova Wall (Version 1)
    思路发现,如果相邻元素的奇偶性相同,那么一定能通过在较低的位置竖着放若干个如果在\(i\)的位置竖着放一块砖头,使得这两列的高度相同。那么,我们想到直接考虑\(h_i\)的奇偶性,即将\(h_i\leftarrowh_i\bmod2\)。如果\(h_i=h_{i+1}\),我们显然可以同时使\(h_i\)和\(h......
  • 2009年-2022年 地级市-环境污染处罚数据
    环境污染处罚数据是环境保护领域中重要的信息资源,它记录了因违反环保法律法规而受到行政处罚或法律制裁的具体情况。这些数据对于提高公众的环保意识、促进企业采取环保措施以及推动环境治理具有重要作用。数据内容概述违法行为的主体:即受到处罚的个人或企业。违法事实:具......
  • python学习笔记-09
    面向对象编程-中面向对象三大特征:封装、继承、多态。封装:把内容封装起来便于后面的使用。对于封装来讲,就是使用__init__方法将内容封装道对象中,然后通过对象直接或者self获取被封装的内容。继承:子继承父的属性和方法。多态:所谓多态就是定义时的类型和运行时的类型不一样......
  • 我主编的电子技术实验手册(09)——并联电路
            本专栏是笔者主编教材(图0所示)的电子版,依托简易的元器件和仪表安排了30多个实验,主要面向经费不太充足的中高职院校。每个实验都安排了必不可少的【预习知识】,精心设计的【实验步骤】,全面丰富的【思考习题】。因此,对于开展电子技术教学犯愁的师生,本专栏应该能够......
  • LeetCode 209.长度最小的子数组
    链接209.长度最小的子数组-力扣(LeetCode)题目给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组[numsl,numsl+1,...,numsr-1,numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。示......
  • 【教学类-36-09】20240622钓鱼(通义万相)-A4各种大小的鱼
    背景需求:用通义万相获得大量的简笔画鱼的图片,制作成不同大小,幼儿用吸铁石钓鱼的纸片(回形针),涂色、排序等补一张通义万相的鱼图素材准备(一)优质的鱼图片(二)剔除的鱼(两个眼睛、很多鱼鳍、不是鱼的造型)(三)模板模板4条(14.2*7.9)模板9条(9.5*5.23)模板10条(9.66*5.62)......
  • [题解]CF609F Frogs and mosquitoes
    思路发现\(x\)对题目的限制较大,因此考虑先将\(x\)排序并离散化后再来考虑。不难用线段树维护\(\max_{i=l}^{r}\{x_i+len_i\}\),这样我们就可以利用类似线段树上二分的技巧得出是哪一只青蛙吃掉的蚊子。但是有可能有一只蚊子无法吃掉,我们先把它丢进一个集合里面。每有......