Offline SageMaker local mode — LightGBM training

Trains against a moto-backed S3/STS endpoint through the sagemaker-local library (no AWS). The job runs in a local Docker container.

Dataset: california_housing (regression), loaded inside the container from scikit-learn. The built sagemaker-local:latest image already includes lightgbm 4.6.0.

Cell 02Code
import os
from dataclasses import replace

from sagemaker.deserializers import JSONDeserializer
from sagemaker.estimator import Estimator
from sagemaker.serializers import JSONSerializer
from sagemaker_local.config import config_from_env
from sagemaker_local.session import make_local_session

cfg = replace(
    config_from_env(),
    bucket="sagemaker-lightgbm",
    image_tag="sagemaker-lightgbm:train",
)
boto_session, sm_session = make_local_session(cfg)

Train

est.fit() runs synchronously in a local container; train.py loads california_housing and writes model.joblib to /opt/ml/model.

The generic Estimator (bring-your-own-container) points at the local image through image_uri, so no AWS image is pulled.

Cell 04Code
est = Estimator(
    entry_point="train.py",
    source_dir=os.path.join(
        os.environ.get("SAGEMAKER_LOCAL_REPO_PATH", "/workspace"),
        "projects",
        "sagemaker_lightgbm",
        "src",
        "sagemaker_lightgbm",
    ),
    image_uri=cfg.image_tag,
    role=cfg.role_arn,
    instance_type="local",
    instance_count=1,
    sagemaker_session=sm_session,
    output_path=f"s3://{cfg.bucket}/models",
    hyperparameters={"dataset": "california_housing"},
)
est.fit()

Deploy & predict

Inputs are 2-D JSON arrays so the default serving input handler parses them correctly.

Cell 06Code
predictor = est.deploy(
    initial_instance_count=1,
    instance_type="local",
    serializer=JSONSerializer(),
    deserializer=JSONDeserializer(),
)
result = predictor.predict([[8.3, 41.0, 6, 1, 1, 1, 38.0, -121.0]])
print("predicted median house value:", result)

Cleanup

Delete the endpoint so the serving container is released and port 8080 is freed.

Cell 08Code
predictor.delete_endpoint()