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
93M Gaussians/sec read | 57M Gaussians/sec write | Auto-optimized
What's New in v0.2.4
- GPU I/O API:
plyread_gpu()andplywrite_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.plywhencompressed=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 filesplywrite(file_path, ...)- Write PLY filesdetect_format(file_path)- Detect format and SH degree
GSData Container:
data.unpack()- Unpack to tupledata.to_dict()- Convert to dictionarydata.copy()- Deep copydata.consolidate()- Optimize for slicingdata[index]- Indexing and slicing
Compression:
compress_to_bytes(data)- Compress to bytescompress_to_arrays(data)- Compress to arraysdecompress_from_bytes(bytes)- Decompress from bytes
Utilities:
sh2rgb(sh)- SH to RGB conversionrgb2sh(rgb)- RGB to SH conversionSH_C0- Normalization constant
GPU Support (PyTorch):
GSTensor.from_gsdata(data, device='cuda')- Convert to GPUgstensor.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
- API Reference - Complete API documentation
- Changelog - Version history and release notes
- Contributing - Contribution guidelines
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:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Run tests and benchmarks
- 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18a4ef6c9fa03c77b20d0fb45117dce58abe74a1c3377d6bd60dd46b837ad99b
|
|
| MD5 |
a883e40c79279cfb96495695d1abc6ad
|
|
| BLAKE2b-256 |
a5b6e8a96a2ec7f07be185b8ed8f7d23bf40798e9f4e8d3cb1172c35cb8c50f6
|
Provenance
The following attestation bundles were made for gsply-0.2.4.tar.gz:
Publisher:
publish.yml on OpsiClear/gsply
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gsply-0.2.4.tar.gz -
Subject digest:
18a4ef6c9fa03c77b20d0fb45117dce58abe74a1c3377d6bd60dd46b837ad99b - Sigstore transparency entry: 708117606
- Sigstore integration time:
-
Permalink:
OpsiClear/gsply@d979b10609aa2c8155dd74409481448730ba4554 -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/OpsiClear
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d979b10609aa2c8155dd74409481448730ba4554 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5de3ff6f29d98fbe940396f92716a21b9d6488cc3058227346cfa9e20bd4de5
|
|
| MD5 |
a6317639210e37258feada635f6e71fd
|
|
| BLAKE2b-256 |
1e730a0bbea152c81583f2c69c5f1444be0ad2c03b09063737adf6f0bd3ce61f
|
Provenance
The following attestation bundles were made for gsply-0.2.4-py3-none-any.whl:
Publisher:
publish.yml on OpsiClear/gsply
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gsply-0.2.4-py3-none-any.whl -
Subject digest:
a5de3ff6f29d98fbe940396f92716a21b9d6488cc3058227346cfa9e20bd4de5 - Sigstore transparency entry: 708117614
- Sigstore integration time:
-
Permalink:
OpsiClear/gsply@d979b10609aa2c8155dd74409481448730ba4554 -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/OpsiClear
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d979b10609aa2c8155dd74409481448730ba4554 -
Trigger Event:
release
-
Statement type: