code: def learn_kmeans(
      feat_dir: Path,
      split: str,
      num_rank: int,
      km_dir: Path,
      n_clusters: int,
      percent: float = -1,
      init: str = "k-means++",
      max_iter: int = 100,
      batch_size: int = 10000,
      tol: float = 0.0,
      n_init: int = 20,
      reassignment_ratio: float = 0.0,
      max_no_improvement: int = 100,
  ) -> None:
      r"""Build and train the KMeans clustering model. The model is saved in "{km_dir}/model.pt"
      Args:
          feat_dir (Path): The directory that stores the feature files.
          split (str): The split of data. Options: [``train``, ``valid``].
          num_rank (int): The number of ranks for multi-processing in feature extraction.
          km_dir (Path): The directory to store the KMeans clustering model.
          n_clusters (int): The number of clusters.
          percent (float): The percent of data for training k-means model.
              If negative, use all data for training. (Default: -1)
          init (str, optional): Method for initialization. Options: [``k-means++``, ``random``].
              (Default: ``k-means++``)
          max_iter (int, optional): Maximum number of iterations over the complete dataset. (Default: 100)
          batch_size (int, optional): Batch size for training the KMeans clustering model. (Default: 10000)
          tol (float, optional): Control early stopping based on the relative center changes as measured by a smoothed,
              variance-normalized of the mean center squared position changes. (Default: 0.0)
          n_init (int, optional): Number of random initializations that are tried. (Default: 20)
          reassignment_ratio (float, optional): Control the fraction of the maximum number of counts for a center
              to be reassigned. A higher value means that low count centers are more easily reassigned. (Default: 0.0)
          max_no_improvement (int, optional): Control early stopping based on the consecutive number of mini batches
              that does not yield an improvement on the smoothed inertia. (Default: 100)
  
      Returns:
          None
      """
      if not km_dir.exists():
          km_dir.mkdir()
  
      km_model = MiniBatchKMeans(
          n_clusters=n_clusters,
          init=init,
          max_iter=max_iter,
          batch_size=batch_size,
          verbose=0,
          compute_labels=False,
          tol=tol,
          max_no_improvement=max_no_improvement,
          init_size=None,
          n_init=n_init,
          reassignment_ratio=reassignment_ratio,
      )
  
      feats, _ = load_feature(
          feat_dir,
          split,
          num_rank,
          percent,
      )
      feats = feats.numpy()
      km_model.fit(feats)
      km_path = _get_model_path(km_dir)
      import joblib
  
      joblib.dump(km_model, km_path)
  
      inertia = -km_model.score(feats) / len(feats)
      _LG.info("Total intertia: %.5f", inertia)
      _LG.info(
          "Finished training the KMeans clustering model successfully"
      )
  
file_path: audio/examples/hubert/utils/kmeans.py
imports: import logging
  from pathlib import Path
  from typing import Tuple
  import torch
  from sklearn.cluster import MiniBatchKMeans
  from torch import Tensor
  from .common_utils import _get_feat_lens_paths, _get_model_path
label_desc: Use image node_id 2 for calling a global function with example usage: learn_kmeans(feat_dir, split, num_rank, km_dir, n_clusters, percent, init, max_iter, batch_size, tol, n_init, reassignment_ratio, max_no_improvement) without return types