code: def test_api_callbacks_fixed_train_steps(tmpdir, csv_filename):
      train_steps = 100
      batch_size = 8
      num_examples = 80
      mock_callback = mock.Mock(wraps=Callback())
  
      input_features = [
          sequence_feature(encoder={"reduce_output": "sum"})
      ]
      output_features = [
          category_feature(
              decoder={"vocab_size": 5}, reduce_input="sum"
          )
      ]
      config = {
          "input_features": input_features,
          "output_features": output_features,
          "combiner": {"type": "concat", "output_size": 14},
          TRAINER: {
              "train_steps": train_steps,
              "batch_size": batch_size,
          },
      }
      model = LudwigModel(config, callbacks=[mock_callback])
      model.train(
          training_set=generate_data(
              input_features,
              output_features,
              os.path.join(tmpdir, csv_filename),
              num_examples=num_examples,
          )
      )
  
      # There are 10 steps per epoch, so 100 train steps => 10 epochs.
      assert mock_callback.on_epoch_start.call_count == 10
  
imports: import json
  import os
  import shutil
  from unittest import mock
  import pandas
  import pytest
  import torch
  import yaml
  from ludwig.api import LudwigModel
  from ludwig.callbacks import Callback
  from ludwig.constants import BATCH_SIZE, ENCODER, TRAINER, TYPE
  from ludwig.globals import MODEL_HYPERPARAMETERS_FILE_NAME
  from ludwig.models.inference import InferenceModule
  from ludwig.utils.data_utils import read_csv
  from tests.integration_tests.utils import category_feature, ENCODERS, generate_data, get_weights, image_feature, run_api_experiment, sequence_feature, text_feature
label_desc: Use image node_id 14 for calling a global function with example usage: test_api_callbacks_fixed_train_steps(tmpdir, csv_filename) without return types