LIVE
1.29°S / 36.82°E  ·  Nairobi

Training and serving H2O models using Amazon SageMaker

Originally published October 30, 2020. Technically restored and annotated September 4, 2026.

Model training and online inference are separate stages of a machine learning pipeline, and they often benefit from different runtimes. Training favors scientific flexibility, manageable cost, and acceptable completion time. Serving favors predictable compatibility, throughput, latency, and operational simplicity. This article demonstrates the resulting architectural principle: train an H2O model from Python, export a portable MOJO artifact, and score that artifact from a separate Java service hosted on Amazon SageMaker. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Compatibility update — September 4, 2026. This is a dated implementation, not a current turnkey deployment guide. The accompanying AWS Samples repository was archived on February 4, 2026 and is read-only. Its trainer targets H2O 3.30, while its predictor pins Java 8, h2o-genmodel 3.30.0.7, Spring Boot 1.5.4.RELEASE, and the amazoncorretto:8 image. Spring Boot 1.x reached end of life in August 2019. Although Amazon currently plans to support Corretto 8 through December 2030, that does not make the application's other dependencies current. ([github.com](https://github.com/aws-samples/amazon-sagemaker-h2o-blog))

Current H2O 3.46.0.12 documentation also states that MOJO and POJO export requires H2O-3 Secure; H2O-3 OSS blocks the relevant export operations, although H2O describes a free MOJO license for non-commercial use. Any reproduction must therefore confirm licensing and rebuild the images with supported, patched dependencies. ([docs.h2o.ai](https://docs.h2o.ai/h2o/latest-stable/h2o-docs/productionizing.html?highlight=mojo))

The underlying AWS container contract remains recognizable: a custom real-time inference image listens on port 8080 and handles health checks at /ping and inference requests at /invocations. Step Functions still integrates with SageMaker operations including hyperparameter tuning, model creation, endpoint configuration, endpoint creation, and endpoint updates; SageMaker endpoint variants can still use Application Auto Scaling. ([docs.aws.amazon.com](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-inference-code.html?utm_source=openai))

The model artifact as the contract

The important idea is not the precise 2020 dependency set. It is the separation between the environment that builds a model and the environment that serves it. A portable artifact can become the contract between those stages, allowing each runtime to be selected, versioned, tested, and scaled according to its own requirements.

H2O binary model. A binary model is tied to the H2O version that created it. Loading it ordinarily requires the same H2O version and a running H2O environment, making it useful for experiments and controlled workflows but a comparatively tight contract for independently maintained serving systems. ([docs.h2o.ai](https://docs.h2o.ai/h2o/latest-stable/h2o-docs/save-and-load-model.html))

POJO. H2O can export a model as Java source that is compiled and scored with h2o-genmodel. POJOs can be embedded in Java applications, but H2O documents compilation and size limitations for very large generated source files. ([docs.h2o.ai](https://docs.h2o.ai/h2o/latest-stable/h2o-docs/productionizing.html?highlight=mojo))

MOJO. A Model Object, Optimized artifact stores the model separately from generic Java scoring code. It is loaded with h2o-genmodel and does not require a running H2O cluster for scoring. H2O documents MOJOs as smaller and, for sufficiently large models, more efficient than generated POJOs. Actual latency still depends on the model, JVM, request path, instance type, concurrency, serialization, and warm-up state, so those advantages should be established with workload-specific tests rather than assumed. ([docs.h2o.ai](https://docs.h2o.ai/h2o/latest-stable/h2o-docs/productionizing.html?highlight=mojo))

Deployment patterns considered in 2020

Pattern A: an H2O.ai algorithm from AWS Marketplace. This minimizes custom packaging because the training and inference images are supplied through a Marketplace algorithm. The H2O-3 GBM algorithm listing remains available, but its supported versions, inputs, terms, and runtime behavior should be checked before use. ([aws.amazon.com](https://aws.amazon.com/marketplace/pp/prodview-rotc3q6vjaqck))

Pattern B: Python training and Python serving with an H2O binary model. This keeps the implementation in Python but couples serving to a compatible H2O runtime and version.

Pattern C: Python training, MOJO export, and Python serving through pyH2oMojo. This preserved a Python-facing application while wrapping Java MOJO scoring. The package described itself as an unofficial wrapper, and its last PyPI release was version 0.1.1 on July 2, 2018. It should not be adopted today without a fresh maintenance, security, and compatibility assessment. ([pypi.org](https://pypi.org/project/pyh2omojo/?utm_source=openai))

Pattern D: Python training, MOJO export, and Java serving. The trainer uses the H2O Python library. The predictor loads the MOJO with h2o-genmodel inside a Spring Boot application running on Amazon Corretto. The original author selected this pattern after trying the alternatives. The article did not publish a controlled benchmark matrix, so the choice should be read as the conclusion of that implementation exercise—not proof that it has the lowest latency or is the best design for every workload. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Problem and dataset

The sample uses the Titanic passenger-survival data associated with Kaggle's Titanic competition. The repository contains separate training and validation CSV files produced from an 80/20 split of the original training data. The H2O GBM example handles missing values such as Age and encodes categorical fields such as Sex and Embarked before training a binary classifier for Survived. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

This is an instructional dataset. It demonstrates the mechanics of preprocessing, hyperparameter tuning, artifact export, endpoint deployment, and invocation; it is not evidence that the resulting model is appropriate for consequential decisions.

Solution architecture

The 2020 solution orchestrates training and deployment with AWS Step Functions and SageMaker. Two images are stored in Amazon Elastic Container Registry: h2o-gbm-trainer, which runs the Python training application, and h2o-gbm-predictor, which runs the Java inference application. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

A manifest.json object uploaded to a designated Amazon S3 location produces an event notification. A Lambda function reads workflow configuration from the manifest and AWS Systems Manager Parameter Store, then starts the parent state machine, ModelTuningWithEndpointDeploymentStateMachine.

The first nested workflow creates a SageMaker hyperparameter tuning job, selects the best model artifact reported by the tuning process, and creates a SageMaker model resource that pairs that artifact with the inference image. The second workflow creates or updates an endpoint configuration and endpoint, then registers the endpoint's production variant with Application Auto Scaling. This sequence is documented in the archived repository, and the principal SageMaker operations remain supported by the current Step Functions integration. ([github.com](https://github.com/aws-samples/amazon-sagemaker-h2o-blog))

Prerequisites

The historical deployment expects an AWS account, an S3 bucket represented below as <s3bucket>, permissions to deploy CloudFormation and AWS SAM resources, Docker, Git, jq, Python, the AWS SAM CLI, Node Package Manager, and sufficient SageMaker quotas. It also expects ml-parameters.json and hyperparameters.json for infrastructure configuration, plus the training image, inference image, SageMaker algorithm resource, training and validation data, and manifest.json for workflow execution. ([github.com](https://github.com/aws-samples/amazon-sagemaker-h2o-blog))

Because the repository is archived, reproduce it only in a controlled account or sandbox. Review every IAM policy, base image, package version, network setting, and generated CloudFormation resource before deployment. Do not treat the repository's historical prerequisites or broad permissions as a current security baseline.

Deploying the workflow infrastructure

The infrastructure is defined with AWS CloudFormation and AWS SAM. Its nested stacks create three applications: ml-parameter-provider for workflow parameters, sagemaker-model-tuner for tuning and training, and sagemaker-endpoint-deployer for endpoint creation, updates, and automatic scaling. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

In the author's 2020 test, infrastructure deployment took approximately two minutes, the tuning jobs completed in approximately four minutes, and endpoint deployment took approximately five to six minutes. The reported test run cost less than one US dollar in eu-central-1. These are historical observations from one run, not current estimates or service-level expectations; present cost and duration depend on region, instance availability, image build time, data size, tuning configuration, and pricing. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Creating the model-training image

The h2o-gbm-trainer project packages the H2O Python training application as a SageMaker custom training image. The archived README identifies the supported line as Python 3.x and H2O 3.30. During a training job, the application reads the training and validation channels, fits an H2O GBM model, reports evaluation metrics for tuning, and exports the selected model as a MOJO artifact. ([github.com](https://github.com/aws-samples/amazon-sagemaker-h2o-blog/tree/master/h2o-gbm-trainer))

The historical project can be built locally and pushed to Amazon ECR through its NPM scripts. For a modern rebuild, pin an explicitly supported H2O release, determine whether MOJO export is licensed for the intended use, generate a software bill of materials, scan the resulting image, and run reproducible artifact-compatibility tests.

Creating the model-inference image

The h2o-gbm-predictor image uses amazoncorretto:8 and packages a Spring Boot application. Its Maven configuration sets Java 1.8, h2o-genmodel 3.30.0.7, and Spring Boot 1.5.4.RELEASE. Those values describe the historical implementation and should not be silently replaced when interpreting its results. ([github.com](https://github.com/aws-samples/amazon-sagemaker-h2o-blog/blob/master/h2o-gbm-predictor/Dockerfile))

The SagemakerLauncher class starts the application. SagemakerController initializes the predictor, loads the MOJO from the model artifact made available to the container, and exposes /ping and /invocations. The current SageMaker custom-container contract still requires a server on port 8080 that handles those paths. AWS recommends that /ping perform a meaningful readiness check rather than return success when the model or critical resources are unavailable. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

The original article also attributed performance and security advantages to Corretto over other OpenJDK distributions. Those comparisons were not accompanied by controlled measurements or exact comparison builds, so they are not retained here as established results. Corretto remains a supported OpenJDK distribution, but the complete application stack—not the JDK alone—must be maintained and benchmarked. ([aws.amazon.com](https://aws.amazon.com/corretto/faqs/?utm_source=openai))

Creating the SageMaker algorithm resource

After the images are published to Amazon ECR, the historical workflow creates an algorithm resource named h2o-gbm-algorithm. A SageMaker algorithm resource can record the training and inference image locations, supported instance types, input channels, hyperparameters, content types, and metrics used by tuning jobs. The CreateAlgorithm API remains available. ([docs.aws.amazon.com](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateAlgorithm.html?utm_source=openai))

The repository's h2o-gbm-algorithm-resource project contains the historical resource definition and deployment scripts.

Running the workflow

Upload the sample training and validation files to the paths expected by manifest.json:

aws s3 cp examples/train.csv s3://<s3bucket>/titanic/training/

aws s3 cp examples/validation.csv s3://<s3bucket>/titanic/validation/

Then upload the manifest to the event-notification prefix:

aws s3 cp examples/manifest.json s3://<s3bucket>/manifests

In the historical stack, that upload invokes the Lambda entry point and starts ModelTuningWithEndpointDeploymentStateMachine. The tuning workflow launches multiple training jobs, evaluates their reported validation metric, identifies the best result, and creates the SageMaker model resource from its MOJO artifact. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Deploying the MOJO endpoint

The endpoint-deployment workflow creates or updates the endpoint configuration, deploys the predictor image with the selected MOJO, waits for the endpoint to enter InService state, and registers the production variant as a scalable target. The sample configures the endpoint to scale between one and four instances. Current SageMaker documentation continues to support automatic scaling of hosted-model variants through Application Auto Scaling. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Endpoint update procedures deserve explicit testing. Current AWS documentation notes that some changes to auto-scaled variants require scaling policies to be removed and the variant deregistered before the endpoint is updated, followed by re-registration after the update. ([docs.aws.amazon.com](https://docs.aws.amazon.com/sagemaker/latest/dg/endpoint-scaling-update.html?utm_source=openai))

Testing the endpoint

Create a request.json file containing the sample passenger record:

{"Pclass":"3","Sex":"male","Age":"22","SibSp":"1","Parch":"0","Fare":"7.25","Embarked":"S"}

Invoke the endpoint with the AWS CLI:

aws sagemaker-runtime invoke-endpoint --endpoint-name survival-endpoint --content-type application/jsonlines --accept application/jsonlines --body fileb://request.json response.json

The fileb prefix passes the request file as raw bytes. If the JSON is instead supplied directly to the blob parameter with AWS CLI version 2, the historical command uses --cli-binary-format raw-in-base64-out because version 2 otherwise treats binary inputs as base64 by default. ([docs.aws.amazon.com](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html?utm_source=openai))

For the model produced in the documented run, the response was:

{"calibratedClassProbabilities":"null","classProbabilities":"[0.686304913500942, 0.313695086499058]","prediction":"0","predictionIndex":0}

That output records the prediction from the particular 2020 training run; it should not be assumed to remain identical after retraining, dependency changes, altered preprocessing, or different hyperparameters. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

The first invocation may include JVM, model-loading, connection, or cache warm-up effects. A client-side round trip also includes network and serialization overhead. Evaluate serving performance with representative payloads, concurrency, traffic distribution, warm and cold conditions, error behavior, and scaling transitions. Report percentiles and resource utilization rather than relying on a few local timings.

Cleaning up

Delete the endpoint, endpoint configuration, model and algorithm resources, tuning and training artifacts, ECR images, S3 objects, Parameter Store entries, Lambda functions, Step Functions state machines, scaling targets, and CloudFormation stacks when they are no longer required. The archived repository retains its historical cleanup instructions, but verify the resources actually created in your account before assuming those scripts are complete. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Conclusion

This implementation separated H2O model development from the online scoring runtime by treating the MOJO as their shared contract. Python supplied the training interface; a Java container supplied the serving interface; SageMaker supplied managed training and hosting; and Step Functions coordinated tuning and deployment.

The portable lesson survives the dated dependencies: when an artifact format permits it, independently choose the training and serving environments, but make compatibility explicit. Pin the artifact producer and consumer, record licenses and dependency versions, test model parity before release, benchmark under representative load, and maintain a rollback path. The 2020 repository demonstrates that pattern historically; it does not establish that its exact containers are secure, supported, or optimal in 2026.

About the author

At the time of publication, the author biography described Anil Sener as a Machine Learning Prototyping Architect working on machine learning, big-data analytics, and data-streaming prototypes for AWS customers in EMEA. ([aws.amazon.com](https://aws.amazon.com/blogs/machine-learning/training-and-serving-h2o-models-using-amazon-sagemaker/))

Original source: AWS Machine Learning Blog. Historical implementation: archived AWS Samples repository.

Responses