silvic-python
silvic-python builds the silvic package, which exposes LightGBM’s Python API over silvic-core. Metal and CUDA training use silvic-gpu, while AWS Neuron training uses silvic-neuron. The silvic.ray module trains one model across Ray actors over the TCP ring of silvic-net.
The extension supports CPython 3.10 or newer through abi3 and runs training without the GIL. Ray, pandas and scikit-learn dependencies are available through the silvic[ray], silvic[pandas] and silvic[sklearn] extras.
pip install silvic
Public API
Dataset(data, label=None, reference=None, weight=None, group=None, feature_name="auto", categorical_feature="auto", params=None)- Training or validation rows from numpy or pandas, binned on first use.
groupholds query sizes, rows sorted by query. pandascategorycolumns become categorical features, and the model stores their levels as LightGBM’s package does.init_scoreis rejected. train(params, train_set, num_boost_round=100, valid_sets=None, valid_names=None, init_model=None, callbacks=None)- Trains and returns a
Booster. A number of iterations inparams, under any alias, wins overnum_boost_round, as in LightGBM.evals_resultandverbose_evalwork as in LightGBM 3.3.5.init_model, aBooster, a path or model text, keeps its trees and addsnum_boost_roundmore; on the rows it was trained on, the result equals training them all in one go. Booster(model_file=None, model_str=None)- A trained model, from
trainor from a LightGBM 3.x or 4.x model of a supported objective. Pickles. booster.predict(data, raw_score=False, num_iteration=None)- LightGBM’s predictions, bit for bit.
binarymodels apply the sigmoid unlessraw_score. booster.model_to_string(),booster.save_model(path)- LightGBM 3.3.5 model text, byte for byte what LightGBM writes. lleaves compiles it.
booster.to_lightgbm()- The same model as a
lightgbm.Booster, to pickle, serve or explain withpred_contrib. log_evaluation(period=1),record_evaluation(result)- LightGBM 4’s callbacks: print every
perioditerations, or record every evaluation into a dict. SilvicRanker,SilvicRegressor,SilvicClassifierLGBMRanker,LGBMRegressorandLGBMClassifier(two classes): the same constructor parameters,fitwithgroup,sample_weight,eval_setandeval_group, andbooster_,feature_importances_,evals_result_. scikit-learn is optional.available_devices()- The runtime devices visible to this process:
cpu, and availablemetal,cudaorneuronaccelerators.
Also public booster.num_trees(), booster.feature_name(), booster.feature_importance(importance_type), CallbackEnv, SilvicModel, and the exceptions below.
Devices
device_type in the parameters picks the backend and gpu_device_id the device. At verbosity 1 or more, training prints the device it runs on.
autodefault- CUDA, then Metal, then the CPU.
gpu- CUDA, then Metal; an error without either.
cpu,metal,cuda- That backend, or an error when it is absent.
neuronLinux, explicit selection- AWS Neuron through
silvic-neuron;gpu_device_idselects a logical NeuronCore. Requires the separate compiler and runtime.
Errors
SilvicError is the base class. ConfigError and DataError are also ValueErrors, as LightGBM raises for bad input; DeviceError, CollectiveError, ModelError and UnsupportedError are also RuntimeErrors. An unknown parameter is a ValueError, as are fobj, feval, learning_rates and early stopping, which silvic does not do. An exception raised in a callback stops training and is raised from train; Ctrl-C raises KeyboardInterrupt.
silvic.ray
import ray
import silvic.ray
booster = silvic.ray.train(
params,
ray.data.read_parquet("s3://bucket/train/"),
label_column="label",
group_column="query_id",
num_workers=5,
use_gpu=True,
num_boost_round=1500,
)
silvic.ray.train(params, train_dataset, *, label_column, group_column=None, num_workers=1, use_gpu=False, ...)- Trains one model across
num_workersactors and returns rank 0’sBooster. Also takesweight_column,feature_columns(every other column by default),categorical_features(integer-coded columns),valid_datasets(a dict of name to dataset),num_boost_round,evals_resultandverbose_eval. resources_per_worker{"CPU": 1}- One placement-group bundle per actor. An explicit
CPUcount also setsnum_threads.use_gpuadds one Ray GPU, which CUDA uses; Metal needs none. Explicitdevice_type="neuron"instead adds oneneuron_coresresource by default; a positive whole-number reservation overrides it. Ray setsNEURON_RT_VISIBLE_CORES. Neuron rejectsuse_gpuand GPU resources. placement_strategy"PACK"- The placement group’s strategy.
timeout_s1800- Bounds placement, the TCP rendezvous, and how long a collective waits for a silent peer.
max_failures3- How many times a lost worker is replaced and training resumed before the run gives up.
checkpoint_period25- Iterations between the checkpoints rank 0 sends the driver; a resume repeats at most this many.
min_workersnum_workers- The fewest workers a resume may continue on when a lost node is not replaced.
replacement_timeout_s300- How long a resume waits for every worker’s bundle to be placed, at each worker count it tries.
ordered_partitions(data, num_workers, *, label_column, ...)- Each worker’s rows in training order, to repeat a distributed run in one process.
Rows go to rank hash(group key) % num_workers, so each actor holds whole queries. One task per input block splits it into a piece per worker, and each actor fetches only its own pieces: the dataset is read once and every row moves once. Each actor then sorts its rows by group key, features, label and weight, an order that depends only on the data and num_workers. The model equals silvic.train on the workers’ rows in rank order, when bin_construct_sample_cnt covers every row.
A lost worker, a reclaimed spot node or a lost object does not end the run. The driver kills the actors, places the group again, and every rank re-loads its rows and trains the remaining trees from the last checkpoint. With the same number of workers, rows and bins are the same, so the model equals an uninterrupted run, byte for byte. When the group can’t be placed in replacement_timeout_s and min_workers is lower, it continues on one worker fewer at a time, repartitioned: a valid model, but no longer the uninterrupted one. It never scales back up. Every resume prints a warning naming the node, the error and the iteration it resumes from.
Other failures are raised at once: an actor’s own exception before a dead actor, and either before the collective errors its peers see. After max_failures resumes, the root error is raised.