Skip to main content

Ultra-fast Gaussian Splatting PLY I/O library - pure Python with NumPy and Numba

Project description

gsply

Ultra-Fast Gaussian Splatting PLY I/O Library

Python License: MIT Tests

93M Gaussians/sec read | 57M Gaussians/sec write | Auto-optimized


What's New in v0.2.4

  • GPU I/O API: plyread_gpu() and plywrite_gpu() - Direct GPU compression/decompression (4-5x faster than CPU + transfer)
  • GPU Compression: Full GPU-accelerated compression pipeline with optimized memory transfers
  • CPU Optimization: Pre-compute ranges for compression (1.44x speedup)

Previous versions:

  • v0.2.2: Data Concatenation, GPU Concatenation, Performance Optimization, Mask Management

Full API Reference | Changelog


Quick Start

from gsply import plyread, plywrite

# Read PLY file (auto-detects format, zero-copy)
data = plyread("model.ply")

# Access fields
positions = data.means    # (N, 3) xyz coordinates
colors = data.sh0         # (N, 3) RGB colors
scales = data.scales      # (N, 3) scale parameters
rotations = data.quats    # (N, 4) quaternions

# Write PLY file (automatically optimized)
plywrite("output.ply", data)

# Write compressed (71-74% smaller)
plywrite("output.ply", data, compressed=True)

Performance: 93M Gaussians/sec read, 57M Gaussians/sec write (400K Gaussians in 6-7ms)

Installation | Examples | API Reference | Performance


Overview

Ultra-fast Gaussian Splatting PLY I/O for Python. Zero-copy reads, auto-optimized writes, optional GPU acceleration.

Key Features:

  • Fast: 93M Gaussians/sec read, 57M Gaussians/sec write
  • Auto-optimized: Writes are 2.6-2.8x faster automatically
  • Pure Python: NumPy + Numba (no C++ compilation)
  • Format support: Uncompressed PLY + PlayCanvas compressed (71-74% smaller)
  • GPU ready: Optional PyTorch integration with GSTensor

Installation

pip install gsply

Dependencies: NumPy and Numba (auto-installed)

Optional GPU acceleration:

pip install torch  # For GSTensor GPU features

Examples

Basic I/O

from gsply import plyread, plywrite

# Read and access data
data = plyread("model.ply")
print(f"Loaded {len(data)} Gaussians")

# Unpack to individual arrays
means, scales, quats, opacities, sh0, shN = data.unpack()

# Write with individual arrays
plywrite("output.ply", means, scales, quats, opacities, sh0, shN)

# Or write directly from GSData
plywrite("output.ply", data)

Format Detection

from gsply import detect_format

is_compressed, sh_degree = detect_format("model.ply")
if is_compressed:
    print("Compressed PlayCanvas format")
else:
    print(f"Uncompressed format with SH degree {sh_degree}")

In-Memory Compression

from gsply import compress_to_bytes, decompress_from_bytes

# Compress for network transfer or storage
compressed_bytes = compress_to_bytes(data)

# Decompress from bytes
data_restored = decompress_from_bytes(compressed_bytes)

GPU Acceleration

from gsply import GSTensor, plyread_gpu, plywrite_gpu

# Direct GPU I/O (4x faster than CPU decompress + GPU transfer)
gstensor = plyread_gpu("model.compressed.ply", device='cuda')

# Access GPU tensors
positions_gpu = gstensor.means  # torch.Tensor on GPU
colors_gpu = gstensor.sh0       # torch.Tensor on GPU

# Filter on GPU
high_opacity = gstensor[gstensor.opacities > 0.5]

# Write back to compressed PLY (GPU compression)
plywrite_gpu("output.compressed.ply", gstensor)

# Or convert from CPU data
data = plyread("model.ply")
gstensor = GSTensor.from_gsdata(data, device='cuda')

# Convert back to CPU
data_cpu = gstensor.to_gsdata()

Data Manipulation

# Slicing and indexing
subset = data[100:200]          # Slice
first = data[0]                 # Single Gaussian
filtered = data[data.opacities > 0.5]  # Boolean mask

# Concatenation
combined = data1.add(data2)     # Pairwise (1.9x faster)
combined = data1 + data2        # Or use + operator
merged = GSData.concatenate([data1, data2, data3])  # Bulk (6.15x faster)

# Optimize for faster operations
data = data.make_contiguous()   # 2-45x speedup for operations

# Copy and modify
bright = data.copy()
bright.sh0 *= 1.5  # Make brighter

Performance

Benchmark Summary

Uncompressed Format (400K Gaussians, SH0):

  • Read: 5.7ms (70M Gaussians/sec)
  • Write: 19.3ms (21M Gaussians/sec)

Compressed Format (400K Gaussians, SH0):

  • Read: 8.5ms (47M Gaussians/sec)
  • Write: 15.0ms (27M Gaussians/sec)
  • Size reduction: 71-74%

Peak Performance:

  • Read: 78M Gaussians/sec (1M Gaussians, SH0, uncompressed)
  • Write: 29M Gaussians/sec (100K Gaussians, SH0, compressed)

GPU Transfer (400K Gaussians, RTX 3090 Ti):

  • With optimization: 1.99ms (11.4x faster)
  • Without optimization: 22.78ms

See detailed performance benchmarks for more information.


Format Support

Uncompressed PLY

Standard binary little-endian PLY format:

SH Degree Properties Description
0 14 xyz, f_dc(3), opacity, scales(3), quats(4)
1 23 + 9 f_rest coefficients
2 38 + 24 f_rest coefficients
3 59 + 45 f_rest coefficients

Compressed PLY (PlayCanvas)

Chunk-based quantized format:

  • Automatically saves as .compressed.ply when compressed=True
  • Compression ratio: 71-74% size reduction
  • Compatible with PlayCanvas, SuperSplat, other WebGL viewers
  • Parallel compression/decompression

API Reference

Complete API documentation is available in docs/API_REFERENCE.md:

Core I/O:

  • plyread(file_path) - Read PLY files
  • plywrite(file_path, ...) - Write PLY files
  • detect_format(file_path) - Detect format and SH degree

GSData Container:

  • data.unpack() - Unpack to tuple
  • data.to_dict() - Convert to dictionary
  • data.copy() - Deep copy
  • data.consolidate() - Optimize for slicing
  • data[index] - Indexing and slicing

Compression:

  • compress_to_bytes(data) - Compress to bytes
  • compress_to_arrays(data) - Compress to arrays
  • decompress_from_bytes(bytes) - Decompress from bytes

Utilities:

  • sh2rgb(sh) - SH to RGB conversion
  • rgb2sh(rgb) - RGB to SH conversion
  • SH_C0 - Normalization constant

GPU Support (PyTorch):

  • GSTensor.from_gsdata(data, device='cuda') - Convert to GPU
  • gstensor.to_gsdata() - Convert to CPU
  • Device management: .to(), .cpu(), .cuda()
  • Precision: .half(), .float(), .double()
  • Full slicing and manipulation support

Development

Setup

# Clone repository
git clone https://github.com/OpsiClear/gsply.git
cd gsply

# Install in development mode
pip install -e .[dev]

# Run tests
pytest tests/ -v

# Run with coverage
pytest tests/ -v --cov=gsply --cov-report=html

Project Structure

gsply/
├── src/gsply/          # Source code
│   ├── gsdata.py       # GSData dataclass
│   ├── reader.py       # PLY reading
│   ├── writer.py       # PLY writing
│   ├── formats.py      # Format detection
│   └── torch/          # PyTorch integration
│       └── gstensor.py # GSTensor GPU dataclass
├── tests/              # Unit tests (169 tests)
├── benchmarks/         # Performance benchmarks
├── docs/               # Documentation
└── pyproject.toml      # Package configuration

Testing

gsply has comprehensive test coverage with 169 passing tests:

# Run all tests
pytest tests/ -v

# Run PyTorch tests (requires torch)
pytest tests/ -v -k "torch or gstensor"

# Run with coverage
pytest tests/ -v --cov=gsply --cov-report=html

Benchmarking

Compare gsply performance against other PLY libraries:

# Install benchmark dependencies
pip install -e .[benchmark]

# Run benchmark
python benchmarks/benchmark.py

# Custom settings
python benchmarks/benchmark.py --config.file path/to/model.ply --config.iterations 20

Documentation


CI/CD

Complete GitHub Actions pipeline:

  • Multi-platform: Ubuntu, Windows, macOS
  • Multi-version: Python 3.10, 3.11, 3.12, 3.13
  • Core + PyTorch testing
  • Automated benchmarking
  • PyPI publishing on release

Contributing

Contributions are welcome! Please see .github/CONTRIBUTING.md for guidelines.

Quick start:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Run tests and benchmarks
  5. Submit a pull request

License

MIT License - see LICENSE file for details.


Citation

If you use gsply in your research, please cite:

@software{gsply2024,
  author = {OpsiClear},
  title = {gsply: Ultra-Fast Gaussian Splatting PLY I/O},
  year = {2024},
  url = {https://github.com/OpsiClear/gsply}
}

Related Projects

  • gsplat: CUDA-accelerated Gaussian Splatting rasterizer
  • nerfstudio: NeRF training framework with Gaussian Splatting support
  • PlayCanvas SuperSplat: Web-based Gaussian Splatting viewer
  • 3D Gaussian Splatting: Original paper and implementation

Made with Python and numpy

Report Bug | Request Feature | Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gsply-0.2.4.tar.gz (94.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gsply-0.2.4-py3-none-any.whl (60.2 kB view details)

Uploaded Python 3

File details

Details for the file gsply-0.2.4.tar.gz.

File metadata

  • Download URL: gsply-0.2.4.tar.gz
  • Upload date:
  • Size: 94.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gsply-0.2.4.tar.gz
Algorithm Hash digest
SHA256 18a4ef6c9fa03c77b20d0fb45117dce58abe74a1c3377d6bd60dd46b837ad99b
MD5 a883e40c79279cfb96495695d1abc6ad
BLAKE2b-256 a5b6e8a96a2ec7f07be185b8ed8f7d23bf40798e9f4e8d3cb1172c35cb8c50f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for gsply-0.2.4.tar.gz:

Publisher: publish.yml on OpsiClear/gsply

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gsply-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: gsply-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 60.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gsply-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a5de3ff6f29d98fbe940396f92716a21b9d6488cc3058227346cfa9e20bd4de5
MD5 a6317639210e37258feada635f6e71fd
BLAKE2b-256 1e730a0bbea152c81583f2c69c5f1444be0ad2c03b09063737adf6f0bd3ce61f

See more details on using hashes here.

Provenance

The following attestation bundles were made for gsply-0.2.4-py3-none-any.whl:

Publisher: publish.yml on OpsiClear/gsply

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page