Skip to content

Repository files navigation

PML — PHP Machine Learning

A production-grade CPU-first AI runtime and machine learning infrastructure framework for PHP.

License: MITPHPBuildPackagistStarsSponsor


PML is to PHP what llama.cpp is to C++ — a high-performance native runtime that brings serious AI computation into an ecosystem the rest of the industry ignores.


What is PML?

PML is a native-accelerated machine learning and AI inference runtime built for PHP. It combines a hand-optimized C tensor engine with a clean PHP orchestration layer, delivering production-grade ML without Python, without CUDA, and without sacrificing throughput.

The architecture is built on a single philosophy: PHP orchestrates, C computes.

Your PHP Application
│
▼
Pml\Tensor / Pml\Dataset ← zero-copy PHP wrappers
│
▼ PHP FFI (single boundary crossing per op)
libtensor.so ← C tensor engine
│
├── OpenBLAS ← BLAS / LAPACK kernels
├── LAPACKE ← eigendecomposition, SVD
├── OpenMP ← multi-threaded batch ops
└── AVX2 ← SIMD acceleration

Every tensor lives as a TensorC* in C memory. PHP holds a reference pointer — never a copy. There are no PHP arrays in any hot path.


Why PML Exists

Modern ML stacks assume Python. This assumption carries hidden costs in PHP-first environments:

Pain PointPython StackPML
Cold-start overhead200–800 ms (interpreter + runtime imports)< 5 ms (PHP + FFI)
Memory per inference150–400 MB baseline8–20 MB baseline
Deployment surfacePython runtime + venv + pipPHP + one .so file
PHP integrationIPC, REST, or subprocessNative function call
CPU parallelismGIL-constrainedOpenMP, zero-GIL

If you run PHP backends, PML lets you embed ML directly — same process, same memory space, same request lifecycle.


Technical Highlights

Zero-Copy Tensor Architecture

// CSV loaded via mmap into C memory — no PHP arrays$ds = Dataset::fromCSV('/data/train.csv');
// Tensor wraps TensorC* — no PHP-side copy$X = $ds->samples(); // Pml\Tensor → TensorC* view// All math crosses FFI exactly once per operation$out = $X->matmul($W)->add($b)->relu();

Tensor is a thin PHP object holding a \FFI\CData pointer. Slices, views, and column extractions reuse the same memory buffer with reference counts tracked entirely inside C.

Native C Tensor Engine

libtensor.so provides:

  • 500+ exported C functions across tensor ops, dataset I/O, inference, autograd, graph execution, and tokenization
  • Fused kernels: addRelu, fusedAdamStep, fusedBceLoss, qw_dot_group (INT8 + fp32 scale)
  • AVX2 SIMD sigmoid, tanh, exp, INT8 dot product
  • OpenBLAS SGEMM for all matmul on contiguous float32 tensors
  • OpenMP threaded batch operations, tree predictions, image pipelines
  • mmap CSV loader: ingests multi-GB datasets without touching PHP memory

LLM Inference Engine

$tok = Tokenizer::fromJson('/models/llama3-8b/tokenizer.json');
$session = InferenceSession::load('/models/llama3-8b', tok: $tok);
// GQA forward pass, KV-cache, streaming tokensforeach ($session->generate("Explain AVX2:", maxNewTokens: 200) as$token) {
echo$token;
}
  • LLaMA / Mistral / Phi architecture support
  • GQA (Grouped Query Attention) natively in C
  • Multi-layer KV-cache (MultiKVCache) — eliminates O(T²) decode cost
  • Milakov online-softmax: O(head_dim) working memory
  • SafeTensors mmap weight loading — zero-copy model ingestion
  • INT8 block quantization (Q8_0-class): 4× memory reduction, AVX2 fused kernel

Classical ML at Native Speed

$pipeline = newPipeline(
transformers: [newStandardScaler(), newPolynomialExpander(degree: 2)],
estimator: newGBDTClassifier(trees: 500, maxDepth: 6)
);
$pipeline->train($dataset);
echo$pipeline->score($test); // accuracy, AUC, F1

GBDT with histogram subtraction + PQ leaf-wise growth. All split-finding runs in C.


Feature Matrix

ModuleDescription
Tensor200+ ops: creation, arithmetic, linear algebra, shape, reductions, fused kernels
DatasetZero-copy mmap CSV, ETL/DataFrame mode, stratified splits, DataLoader, streaming
Estimators19 classifiers, 15 regressors, 6 anomaly detectors, 5 clusterers, decomposition
TransformersScalers, encoders, NLP vectorizers, image transforms, feature selection, imputers
Neural Networks29 layer types, 9 optimizers, 5 losses, early stopping, callbacks, mixed precision
QuantizationINT8 block quantization, QuantizedTensor, Dense::quantize(), Sequential::quantize()
InferenceLLM forward pass, GQA, KV-cache, BPE tokenizer, SafeTensors I/O, streaming
Vision106 C functions: image I/O, augmentation, MobileNetV3, YOLO11n, NanoDet, FastSAM
PipelineTransformer composition, 6 CV strategies, GridSearch, ensemble, BootstrapAggregator
AutogradReverse-mode AD, compute graph, Variable API

Installation

Requirements

DependencyVersionPurpose
PHP≥ 8.1Runtime
ext-ffianyC bridge
GCC≥ 11Compile backend
libopenblas-devanyBLAS kernels
liblapacke-devanyLinear algebra
Linux x86_64AVX2 / OpenMP
# Ubuntu / Debian
sudo apt install gcc libopenblas-dev liblapacke-dev
# Install PHP library
composer require ghostjat/pml
# Build the C backend (once per machine)cd vendor/ghostjat/pml/src/Lib
gcc -O3 -march=native -mfma -fopenmp -funroll-loops -fomit-frame-pointer \
-D_GNU_SOURCE -shared -fPIC -funsafe-math-optimizations \
-o libtensor.so.7 tensor.c dataset_io.c inference.c autograd.c graph.c tokenizer.c \
-lopenblas -llapacke -lm
ln -sf libtensor.so.7 libtensor.so

php.ini settings:

ffi.enable = true
memory_limit = 2G
opcache.jit = tracing
opcache.jit_buffer_size = 128M

Quick Start

Classical Classification

<?phprequire'vendor/autoload.php';
usePml\Dataset;
usePml\Pipeline;
usePml\Transformers\StandardScaler;
usePml\Estimators\Classifiers\RandomForestClassifier;
$dataset = Dataset::fromCSV('iris.csv', hasHeader: true)
->withLabelColumn('species')
->dropNans();
[$train, $test] = $dataset->stratifiedSplit(testRatio: 0.2);
$pipeline = newPipeline(
transformers: [newStandardScaler()],
estimator: newRandomForestClassifier(trees: 200)
);
$pipeline->train($train);
echo"Accuracy: " . $pipeline->score($test) . PHP_EOL;
$pipeline->save('/models/iris');

Deep Learning (MLP with early stopping)

<?phpusePml\NeuralNetwork\Sequential;
usePml\NeuralNetwork\Layers\{Dense, BatchNormalization, Dropout, ReLU, Softmax};
usePml\NeuralNetwork\Optimizers\Adam;
usePml\NeuralNetwork\Losses\CrossEntropyLoss;
usePml\Training\{Trainer, TrainingArguments};
$model = newSequential([
newDense(784, 512), newBatchNormalization(), newReLU(), newDropout(0.3),
newDense(512, 256), newBatchNormalization(), newReLU(), newDropout(0.2),
newDense(256, 10), newSoftmax(),
], newAdam(lr: 1e-3), newCrossEntropyLoss());
$trainer = newTrainer($model, newTrainingArguments(
epochs: 30, batchSize: 128, patience: 5,
));
$result = $trainer->train($trainDataset, $valDataset);
echo"Best accuracy: {$result->bestMetric}" . PHP_EOL;

INT8 Quantized Deployment

<?php// Quantize after training — 4× memory reduction, same API$model->quantize(groupSize: 32);
$predictions = $model->predict($testDataset);

LLM Inference (LLaMA / Mistral)

<?phpusePml\Inference\{InferenceSession, Tokenizer};
$tok = Tokenizer::fromJson('/models/mistral-7b/tokenizer.json');
$session = InferenceSession::load('/models/mistral-7b', tok: $tok);
foreach ($session->generate("Write a PHP FFI binding:", maxNewTokens: 300) as$token) {
echo$token;
flush();
}

Computer Vision

<?phpusePml\Vision\{Image, Yolo11n, MobileNetV3};
$detector = newYolo11n('/models/yolo11n.weights', confidenceThresh: 0.5);
$classifier = newMobileNetV3('/models/mobilenetv3.weights');
$img = Image::fromFile('scene.jpg');
$dets = $detector->detect($img);
foreach ($detsas$box) {
$label = $classifier->classify($img->crop(...$box->rect));
echo"{$label} @ {$box->confidence}" . PHP_EOL;
}

Benchmarks

Benchmarks run on AMD Ryzen 9 5950X, 64 GB DDR4-3600, Ubuntu 22.04, GCC 13, PHP 8.3. Full methodology in BENCHMARKS.md.

Tensor Throughput — GEMM 1024×1024

RuntimeTimeGFLOPS
PML (OpenBLAS + AVX2)18 ms116
RubixML (PHP arrays)4,200 ms0.5
NumPy (MKL)14 ms150
PyTorch CPU22 ms95

Cold-Start to First Inference

RuntimeCold Start
PML4 ms
Python + scikit-learn210 ms
Python + PyTorch680 ms

Memory: 10-class MLP Training (50K samples)

RuntimeRSS Peak
PML38 MB
PyTorch290 MB
TensorFlow410 MB

Architecture

See ARCHITECTURE.md for the full design document.

┌─────────────────────────────────────────────────────────┐
│ Your PHP Application │
└─────────────────────────────┬───────────────────────────┘
│ PSR-4 autoload
┌─────────────────────────────▼───────────────────────────┐
│ PML PHP Layer │
│ Tensor · Dataset · Pipeline · Sequential · │
│ InferenceSession · Vision · Estimators · Transformers │
└─────────────────────────────┬───────────────────────────┘
│ FFI::cdef() — one crossing per op
┌─────────────────────────────▼───────────────────────────┐
│ libtensor.so (C tensor engine) │
│ tensor.c · dataset_io.c · inference.c · autograd.c │
│ graph.c · tokenizer.c │
│ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ OpenBLAS │ │ LAPACKE │ │ OpenMP │ │
│ └──────────────┘ └─────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘

Roadmap Preview

VersionFocusStatus
v1.0–1.3Tensor engine, classical ML, deep learning, LLM inference, INT8, vision✅ Done
v2.0Vulkan GPU backend (cross-vendor: NVIDIA / AMD / Intel / Apple)🔄 Design
v2.1ONNX model import, fp16 tensors, Flash Attention📋 Planned
v3.0Distributed training, sharded datasets, agent runtime📋 Planned

Full roadmap: ROADMAP.md


Comparison

PMLscikit-learnPyTorch CPURubixML
LanguagePHP + CPython + CPython + C++PHP
Tensor engineNative C (libtensor.so)NumPyLibTorchPHP arrays
Zero-copy I/O✅ mmap
PHP-native API
LLM inference✅ GQA, KV-cache
INT8 quantization✅ AVX2 fused
Vision (detection)✅ YOLO11n, NanoDet
Cold-start4 ms210 ms680 ms60 ms
Deployment.so filePython envPython envComposer

Contributing

Read CONTRIBUTING.md for the full guide. Key rules:

  • PHP orchestrates — heavy loops must stay in C
  • Preserve zero-copy semantics everywhere possible
  • New C functions must be declared in tensor.h and bound in TensorEngine.php
  • All PRs require PHPUnit + PHPBench results
  • Performance regressions block merge
composer install
vendor/bin/phpunit --colors=always
vendor/bin/phpbench run --report=aggregate

Sponsors

PML is an independent open-source project. Sponsorship funds C kernel development, GPU backend work, documentation, and infrastructure.

❤ Become a Sponsor

See SPONSORS.md for tier details and benefits.


License

MIT — Copyright (c) 2024 Shubham Chaudhary


PHP orchestrates. C computes. Zero compromises.