Updated on 2026-11-06 GMT+08:00

Operator Base Classes and Differences

When developing a custom operator, you need to choose an appropriate operator base class to inherit. Different base classes are suitable for different processing scenarios, such as row-level transformation, batch filtering, and one-to-many generation. This section details the inheritance hierarchy, key parameters, difference comparison, and selection suggestions for the 5 operator base classes provided by the SDK to help you quickly choose the right base class.

Operator Base Classes

Inheritance is a core concept in object-oriented programming: a subclass automatically acquires all attributes and methods of its parent class, while also being able to override parent class methods to implement custom logic. By inheriting an SDK base class, custom operators only need to implement the process method to complete the development of data processing logic.

OP (Parent base class, which cannot be used directly)
├── Mapper         — Row-level transformation/labeling operator
├── BatchMapper    — Batch transformation/labeling operator
├── Filter         — Row-level filtering operator
├── BatchFilter    — Batch filtering operator
└── Generator      — One-to-many operator (one sample generates multiple samples)

The key information comparison of each operator base class is shown in the following table. For parameter descriptions of the OP parent base class, see OP Parent Base Class Parameters.

Operator Base Class

Processing Granularity

Typical Scenario

PreProcess

(Optional)

Process

(Mandatory)

PostProcess

(Optional)

process Method Input

process Method Return Value

Whether New Column Type Must Be Declared (Optional)

Filter

Single sample

Row-level filtering

Supported

Supported

Supported

dict[str, Any]

bool

No

Mapper

Single sample

Row-level labeling/transformation

Supported

Supported

Supported

dict[str, Any]

dict[str, Any] (One or more columns can be added.)

Yes (Override __return_extend_columns_type__().)

BatchMapper

Batch samples

Batch labeling/transformation

Supported

Supported

Not supported

dict[str, pa.Array]

pa.Array (Use pa.struct type for multiple columns)

Yes (Override __return_extend_columns_type__().)

BatchFilter

Batch samples

Batch filtering

Not supported

Supported

Supported

dict[str, pa.Array]

pa.Array(bool)

No

Generator

Single sample

One-to-many generation

Not supported

Supported

Not supported

dict[str, Any]

list[dict[str, Any]]

No

OP Parent Base Class Parameters

OP is the top-level base class for all operators and cannot be inherited directly. It defines the common attributes and methods of operators. Key parameter descriptions are shown in the following table.

Parameter

Type

Source

Description

op_args

dict[str, Any]

User-defined

User-defined operator parameters. Passed via interface configuration during operator creation and retrieved via __init__ in code.

content_type

str

System-injected

Current dataset type, corresponding to the DatasetType enum value.

input_columns

list[str]

System-injected

List of input column names processed by the operator. Do not define it in op_args.

_accelerator

str

Developer-defined

Accelerator type. Optional values: cpu (default) or npu.

_max_concurrency

int

Developer-defined

Maximum concurrency. Decrease it to prevent OOM errors; increase to boost throughput.

Selection Suggestions

Decision process for choosing a base class:
  I want to transform/label data → Mapper (row-level) or BatchMapper (batch)
  I want to filter data → Filter (row-level) or BatchFilter (batch)
  I want to generate multiple items from one → Generator
Row-level vs. batch:
  No model inference needed → Row-level (Mapper/Filter), simpler logic
  Model inference needed → Batch (BatchMapper/BatchFilter), higher throughput
Selection advice for row-level and batch operators:
  • Row-level operators (Mapper/Filter): Processed one by one with simple logic, suitable for scenarios that do not require batch inference.
  • Batch operators (BatchMapper/BatchFilter): Processed in batches at the column level, suitable for scenarios requiring model batch inference to significantly boost throughput.

Dataset Types and Fields

The SDK has built-in dataset entity classes used to parse and construct sample data within operators.

Dataset Type

Field

Import Path

PreTrainText (Pre-training text)

text (str)

from modelarts.data.refiner.dataset.dpt import PreTrainText

Messages (OpenAI Messages format)

messages (List[Message]), where each Message contains role (str) and content (str)

from modelarts.data.refiner.dataset.sft import Messages, Message

Image (Image)

file_path (str), record (Optional[bytes]), height (int), width (int)

from modelarts.data.refiner.dataset.image import Image

Video (Video)

file_path (str), duration (float), fps (float), height (int), width (int), frame_count (int)

from modelarts.data.refiner.dataset.video import Video

Each dataset entity class provides three static methods: from_dict(sample): Converts a dictionary into an object. to_dict(obj): Converts an object into a dictionary. check(sample): Validates the sample format.

FAQs

  • Can multiple classes be defined in process.py?

    Yes. However, only the three class names PreProcess, Process, and PostProcess will be recognized and executed. You can define helper classes and functions for these three classes to call.

  • Can PreProcess and PostProcess inherit different base classes?

    Yes. The three processing stages can inherit different operator base classes; for example, PreProcess inherits Filter (filtering) and Process inherits Mapper (labeling).

  • What is the difference between the return values of Mapper and BatchMapper's process methods?

    Mapper's process returns dict[str, Any], representing key-value pairs of newly added columns for a single sample; BatchMapper's process returns pa.Array, representing the results of an entire column of batch data.

  • When does __return_extend_columns_type__() need to be implemented?

    It only needs to be implemented when the operator type is Mapper or BatchMapper to declare the types of newly added columns. Filter, BatchFilter, and Generator do not need to implement this method.

  • How do I declare return types for multiple columns?
    @staticmethod 
    def __return_extend_columns_type__() -> daft.schema.Schema: 
        return daft.schema.Schema.from_pydict({ 
            'score': daft.DataType.int64(), 
            'label': daft.DataType.string(),
            'confidence': daft.DataType.float64(),
        })
  • How does Generator's return value differ from other operators?

    Generator's process returns list[dict[str, Any]], where each element is a complete new sample (containing all columns), whereas Mapper only needs to return the newly added columns. Generator is suitable for scenarios where one sample generates multiple samples.