https://github.com/ray-project/distributed-zkml
Distributed Proofs with ZMKL and Ray
https://github.com/ray-project/distributed-zkml
Last synced: 15 days ago
JSON representation
Distributed Proofs with ZMKL and Ray
- Host: GitHub
- URL: https://github.com/ray-project/distributed-zkml
- Owner: ray-project
- Created: 2025-12-18T01:04:46.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-01-05T03:57:04.000Z (7 months ago)
- Last Synced: 2026-01-07T12:19:28.182Z (6 months ago)
- Language: Rust
- Size: 13.5 MB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# distributed-zkml
Extension of [zkml](https://github.com/uiuc-kang-lab/zkml) for distributed proving using Ray, layer-wise partitioning, and Merkle trees.
> **⚠️ Status Note:** This is an experimental research project. Also consider [zk-torch](https://github.com/uiuc-kang-lab/zk-torch).
## Completed Milestones
1. ~~**Make Merkle root public**: Add root to public values so next chunk can verify it~~ Done
2. ~~**Complete proof generation**: Connect chunk execution to actual proof generation ([#8](https://github.com/ray-project/distributed-zkml/issues/8))~~ Done
3. ~~**Ray-Rust integration**: Connect Python Ray workers to Rust proof generation ([#9](https://github.com/ray-project/distributed-zkml/issues/9))~~ Done
4. ~~**GPU acceleration**: ICICLE GPU backend for MSM operations ([#10](https://github.com/ray-project/distributed-zkml/issues/10))~~ Done - see [GPU Acceleration](#gpu-acceleration)
---
## Table of Contents
- [Status and Limitations](#status-and-limitations)
- [Overview](#overview)
- [Implementation](#implementation)
- [How Distributed Proving Works](#how-distributed-proving-works)
- [Security Model and Trust Boundaries](#security-model-and-trust-boundaries)
- [Structure](#structure)
- [Requirements](#requirements)
- [Quick Start](#quick-start)
- [GPU Acceleration](#gpu-acceleration)
- [Testing](#testing)
- [References](#references)
---
## Status and Limitations
### Project Status
This project implements a **Ray-based distributed proving approach** for zkml. It is experimental research code and should be considered useful for studying alternative approaches to zkML parallelization. The current status lacks formal security analysis and proof composition.
### Known Limitations
**Proof Composition**: This implementation generates separate proofs per chunk. It does not implement recursive proof composition or aggregation. Verifiers must check O(n) proofs rather than O(1), limiting succinctness.
**Trust Domain**:
- **Merkle trees provide privacy for proof readers, not compute providers**: The prover must know all weights and activations to generate a valid ZK proof. Merkle trees hide intermediate values from people *reading the published proof*, not from the compute provider *during execution*.
- **Multi-party security requires different trust domains**: Security only applies when chunks are distributed across different trust domains (e.g., your servers + AWS), not just different AWS regions.
- **Comparison to TEE/FHE/MPC**: Trusted Execution Environments (TEEs), Fully Homomorphic Encryption (FHE), or Multi-Party Computation (MPC) provide stronger privacy guarantees but at significant costs that are beyond the threshold of scalable AI applications.
### When to Use This
**Consider this project if:**
- Researching alternative zkml parallelization approaches
- Need examples of Ray integration for cryptographic workloads
- Studying Merkle-based privacy for intermediate computations
- Building distributed halo2 proving (not zkML-specific)
- **Use case**: You trust compute providers but want to limit public proof exposure, or model is partitioned across multiple non-colluding organizations
**Use alternatives if:**
- Need to hide data from compute providers themselves → Requires TEEs/FHE/MPC
- Need single aggregated proof → Consider [zk-torch](https://github.com/uiuc-kang-lab/zk-torch)
---
## Overview
This repository extends zkml (see [ZKML paper](https://ddkang.github.io/papers/2024/zkml-eurosys.pdf)) with distributed proving capabilities. zkml provides an optimizing compiler from TensorFlow to halo2 ZK-SNARK circuits.
distributed-zkml adds:
- **Layer-wise partitioning**: Split ML models into chunks for parallel proving across GPUs via Ray
- **Merkle tree commitments**: Hash intermediate activations with Poseidon; only publish root in proof
- **ICICLE GPU acceleration**: Hardware-accelerated MSM operations
### Comparison to zkml
| Feature | zkml | distributed-zkml |
|---------|------|------------------|
| Architecture | Single-machine | Distributed across GPUs |
| Scalability | Single GPU memory | Horizontal scaling |
| Privacy | Outputs public | Intermediate values hidden from proof readers via Merkle trees |
## Implementation
### How Distributed Proving Works
1. **Model Partitioning**: Split model into chunks at layer boundaries
2. **Parallel Execution**: Each chunk runs on a separate GPU via Ray
3. **Merkle Commitments**: Hash intermediate outputs with Poseidon, only root is public
4. **On-Chain**: Publish only the Merkle root (O(1) public values vs O(n) without)
**Note**: Each chunk produces a separate proof. This implementation does not aggregate proofs into a single succinct proof. Verifiers must check all chunk proofs individually (O(n) verification time). For single-proof aggregation, see [zk-torch](https://github.com/uiuc-kang-lab/zk-torch)'s accumulation-based approach.
```
Model: 9 layers -> 3 chunks
Chunk 1: Layers 0-2 -> GPU 1 -> Hash A
Chunk 2: Layers 3-5 -> GPU 2 -> Hash B
Chunk 3: Layers 6-8 -> GPU 3 -> Hash C
Merkle Tree:
Root (public)
/ \
Hash(AB) Hash C
/ \
Hash A Hash B
```
### Trust Boundaries
#### What Merkle Trees Provide
| Scenario | Hidden? | Explanation |
|----------|---------|-------------|
| Proof readers reconstructing weights via model inversion | Yes | Intermediate activations are hashed, not exposed in proof |
| Compute provider seeing weights during execution | No | Provider must have weights to generate ZK proof |
| Compute provider seeing intermediate activations during execution | No | Provider computes them |
**Key insight:** Merkle trees hide intermediate values from people *reading the published proof*, not from the compute provider *during execution*. The prover must know all values to generate a valid ZK proof.
#### Multi-Party Proving and Trust Domains
Security depends on **trust domains**, not physical location:
| Setup | Trust Domains | What's Private |
|-------|---------------|----------------|
| Single AWS account (any region) | 1 | Nothing from AWS — they control all regions |
| Your servers + AWS | 2 | Your portion's weights never sent to AWS |
| AWS + Google + Azure | 3 | Each provider sees only their chunk (assuming non-collusion) |
**Multi-party benefit:** If model is partitioned across different trust domains (e.g., your servers + AWS), no single party has the full model. Combined with Merkle trees, this provides layered privacy:
- **Partitioning** → limits what any single provider can access
- **Merkle trees** → limits what proof readers can observe
#### Comparison with ZKTorch
| Aspect | distributed-zkml | ZKTorch |
|--------|------------------|---------|
| Scaling strategy | Horizontal (more machines via Ray) | Vertical (proof compression via Mira) |
| Final output | N separate proofs | 1 accumulated proof |
| Verification cost | O(N) proofs to verify | O(1) single proof |
| Intermediate privacy | Merkle trees hide from proof readers | Exposed in proof |
| Base system | halo2 (~30M param limit) | Custom pairing-based (6B params tested) |
**These approaches are orthogonal** — could theoretically combine Ray parallelism with Mira accumulation.
### Structure
```
distributed-zkml/
├── python/ # Python wrappers for Rust prover
├── tests/ # Distributed proving tests
└── zkml/ # zkml (modified for Merkle + chunking)
├── src/bin/prove_chunk.rs
└── testing/
```
## Requirements
### Docker (Recommended)
Just Docker and Docker Compose. Everything else is in the container.
### Native Build
| Dependency | Notes |
|------------|-------|
| Rust (nightly) | Install via [rustup](https://rustup.rs/) |
| Python >=3.10 | |
| pip | `pip install -e .` |
| Build tools | Linux: `build-essential pkg-config libssl-dev`; macOS: Xcode CLI |
**Python deps** (installed via `pip install -e .`):
- `ray[default]>=2.31.0`
- `msgpack`, `numpy`
**Optional**: NVIDIA GPU + CUDA 12.x + ICICLE backend for GPU acceleration
---
## Quick Start
### Docker
```bash
docker compose build dev
docker compose run --rm dev
# Inside container:
cd zkml && cargo test --test merkle_tree_test -- --nocapture
```
### Native
```bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build
cd zkml && rustup override set nightly && cargo build --release && cd ..
# Python deps
pip install -e .
```
---
## GPU Acceleration
Uses [ICICLE](https://github.com/ingonyama-zk/icicle) for GPU-accelerated MSM (Multi-Scalar Multiplication).
### Requirements
- NVIDIA GPU (tested on A10G/T4, compatible with A100/H100)
- CUDA 12.x
- Ubuntu 20.04+
### Setup
```bash
# 1. Download ICICLE backend (Ubuntu 22.04 - use ubuntu20 for 20.04)
curl -L -o /tmp/icicle.tar.gz \
https://github.com/ingonyama-zk/icicle/releases/download/v3.1.0/icicle_3_1_0-ubuntu22-cuda122.tar.gz
# 2. Install
mkdir -p ~/.icicle && tar -xzf /tmp/icicle.tar.gz -C /tmp && cp -r /tmp/icicle/lib/backend ~/.icicle/
# 3. Set env var (add to ~/.bashrc)
export ICICLE_BACKEND_INSTALL_DIR=~/.icicle/backend
# 4. Build with GPU
cd zkml && cargo build --release --features gpu
# 5. Verify
cargo test --test gpu_benchmark_test --release --features gpu -- --nocapture
```
Expected output:
```
Registered devices: ["CUDA", "CPU"]
Successfully set CUDA device 0
```
### Benchmarks (T4)
| Size | GPU MSM Time | Throughput |
|------|--------------|------------|
| 2^14 (16K) | 6.5ms | 2.5M pts/sec |
| 2^16 (65K) | 7.9ms | 8.3M pts/sec |
| 2^18 (262K) | 13ms | 19.5M pts/sec |
### FFT/NTT Notes
- **Measure FFT time**: `HALO2_FFT_STATS=1`
- **GPU NTT (experimental)**: `HALO2_USE_GPU_NTT=1` - currently slower due to conversion overhead
---
## Testing
### Distributed Proving
```bash
# Simulation (fast)
python tests/simple_distributed.py \
--model zkml/examples/mnist/model.msgpack \
--input zkml/examples/mnist/inp.msgpack \
--layers 4 --workers 2
# Real proofs
python tests/simple_distributed.py ... --real
```
### Rust Tests
```bash
cd zkml
cargo test --test merkle_tree_test --test chunk_execution_test -- --nocapture
```
### CI
Runs on PRs to `main`/`dev`: builds zkml, runs tests (~3-4 min). GPU tests excluded to save costs.
---
## References
- [ZKML Paper](https://ddkang.github.io/papers/2024/zkml-eurosys.pdf) (EuroSys '24) - Original zkml framework
- [zkml Repository](https://github.com/uiuc-kang-lab/zkml) - Base framework this project extends
- [zk-torch](https://github.com/uiuc-kang-lab/zk-torch) - Alternative approach using proof accumulation/folding.