code: def _balance_blocks(
      kvs,
      partition_order_mappings: dict = None,
      block_row_size: int = None,
  ):
      block_id = None
      previous_blocks = list()
      for _, blocks in kvs:
          if block_id is None and len(blocks[0]):
              sample_id = blocks[0][0]
              block_id = partition_order_mappings[sample_id][
                  "start_block_id"
              ]
  
          if previous_blocks:
              blocks = [
                  Block.vstack([pre_block, block])
                  for pre_block, block in zip(previous_blocks, blocks)
              ]
              previous_blocks = list()
  
          row_size = len(blocks[0])
          for i in range(0, row_size, block_row_size):
              if row_size - i < block_row_size:
                  previous_blocks = [
                      block[i:row_size] for block in blocks
                  ]
              else:
                  yield block_id, [
                      block[i : i + block_row_size] for block in blocks
                  ]
                  block_id += 1
  
      if previous_blocks:
          yield block_id, previous_blocks
  
      if block_id is None:
          return []
  
imports: import copy
  import functools
  from typing import List, Union
  import torch
  from sklearn.utils import resample
  from .._dataframe import DataFrame
  from ..manager.data_manager import DataManager
  from ..manager.block_manager import Block
  from ._compress_block import compress_blocks
  from ._indexer import get_partition_order_by_raw_table, get_partition_order_mappings_by_block_table
  from ._promote_types import promote_partial_block_types
  from ._set_item import set_item
  from fate.arch.tensor import DTensor
label_desc: Use image node_id 8 for calling a global function with example usage: _balance_blocks(kvs, partition_order_mappings, block_row_size) and returns: list