Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Haifengl Smile Read Object API

From Leeroopedia


Overview

The Read.object() static method is the primary API for deserializing trained Smile ML models from .sml files. It reads a binary file produced by Write.object(), reconstructs the serialized Java object graph using ObjectInputStream, and returns the result as a generic Object. The caller then casts it to the appropriate type (typically smile.model.Model).

Source Location

Item Location
Read interface base/src/main/java/smile/io/Read.java (Lines 52-59)
Write interface base/src/main/java/smile/io/Write.java (Lines 54-60)
Model interface core/src/main/java/smile/model/Model.java

Import Statements

import smile.io.Read;
import smile.io.Write;
import java.nio.file.Path;
import java.io.IOException;

External Dependencies

Dependency Package Purpose
Java Serialization java.io.ObjectInputStream Deserializes object from byte stream
Java Serialization java.io.ObjectOutputStream Serializes object to byte stream (Write side)
Java NIO java.nio.file.Files, java.nio.file.Path File I/O operations

Type

API Doc

API Signature

Read.object() -- Deserialization

public interface Read {
    /**
     * Reads a serialized object from a file.
     * @param path the file path.
     * @return the serialized object.
     * @throws IOException when fails to read the stream.
     * @throws ClassNotFoundException when fails to load the class.
     */
    static Object object(Path path) throws IOException, ClassNotFoundException;
}

Write.object() -- Serialization

public interface Write {
    /**
     * Writes a serializable object to a file.
     * @param o the object to serialize.
     * @param path the file path.
     * @throws IOException when fails to write the stream.
     */
    static void object(Serializable o, Path path) throws IOException;
}

Inputs and Outputs

Method Inputs Outputs Exceptions
Read.object() Path path -- absolute or relative path to a .sml file Object -- the deserialized object (cast to Model at runtime) IOException if file cannot be read; ClassNotFoundException if the serialized class is not on the classpath
Write.object() Serializable o -- the object to persist; Path path -- destination file void IOException if file cannot be written

Implementation Details

The Read.object() implementation is straightforward:

static Object object(Path path) throws IOException, ClassNotFoundException {
    InputStream file = Files.newInputStream(path);
    ObjectInputStream in = new ObjectInputStream(file);
    Object o = in.readObject();
    in.close();
    file.close();
    return o;
}

Step-by-step breakdown:

  1. Opens an InputStream to the file at the given Path using Files.newInputStream().
  2. Wraps the raw stream in an ObjectInputStream which handles the Java serialization protocol.
  3. Calls readObject() to reconstruct the full object graph from the binary data.
  4. Closes both streams explicitly.
  5. Returns the reconstructed object as a generic Object.

The corresponding Write.object() mirrors this process:

static void object(Serializable o, Path path) throws IOException {
    OutputStream file = Files.newOutputStream(path);
    ObjectOutputStream out = new ObjectOutputStream(file);
    out.writeObject(o);
    out.close();
    file.close();
}

Usage Examples

Saving a Trained Model

import smile.io.Write;
import smile.model.Model;
import smile.data.formula.Formula;
import java.nio.file.Path;

// Train a classification model
Formula formula = Formula.lhs("species");
var model = Model.classification("random-forest", formula, irisData, null, params);

// Add metadata tags
model.setProperty(Model.ID, "iris-classifier");
model.setProperty(Model.VERSION, "2");

// Serialize to .sml file
Write.object(model, Path.of("/models/iris-classifier.sml"));

Loading a Model for Inference

import smile.io.Read;
import smile.model.Model;
import smile.model.ClassificationModel;
import java.nio.file.Path;

// Deserialize the model
Object obj = Read.object(Path.of("/models/iris-classifier.sml"));

// Cast to the Model interface
Model model = (Model) obj;

// Inspect metadata
System.out.println("Algorithm: " + model.algorithm());    // "random-forest"
System.out.println("Schema: " + model.schema());
System.out.println("ID: " + model.getTag(Model.ID));      // "iris-classifier"
System.out.println("Version: " + model.getTag(Model.VERSION)); // "2"

// Use for prediction (via ClassificationModel)
if (model instanceof ClassificationModel cm) {
    int prediction = cm.predict(inputTuple);
}

How InferenceService Uses Read.object()

In the serve module, InferenceService calls Read.object() at startup to load models:

private void loadModel(Path path) {
    try {
        logger.infof("Loading model from '%s'", path);
        var obj = Read.object(path);          // <-- deserialization happens here
        if (obj instanceof Model dummy) {
            var model = new InferenceModel(dummy, path);
            models.put(model.id(), model);
        } else {
            logger.errorf("'%s' is not a valid model", path);
        }
    } catch (Exception ex) {
        logger.errorf(ex, "Failed to load model '%s'", path);
    }
}

The loaded object is validated with instanceof Model before being wrapped in an InferenceModel and registered in the model map.

Related

Principle:Haifengl_Smile_Model_Serialization

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment