class_docstr: A worker class that executes (a partition of) the model on a GPU.
  
  Each worker is associated with a single GPU. The worker is responsible for
  maintaining the KV cache and executing the model on the GPU. In case of
  distributed inference, each worker is assigned a partition of the model.
code: def _prepare_inputs(
      self,
      seq_group_metadata_list: List[SequenceGroupMetadata],
  ) -> Tuple[torch.Tensor, torch.Tensor, InputMetadata]:
      seq_groups: List[Tuple[List[int], SamplingParams]] = []
      input_tokens: List[int] = []
      input_positions: List[int] = []
      slot_mapping: List[int] = []
  
      # Add prompt tokens.
      prompt_lens: List[int] = []
      for seq_group_metadata in seq_group_metadata_list:
          if not seq_group_metadata.is_prompt:
              continue
  
          seq_ids = list(seq_group_metadata.seq_data.keys())
          sampling_params = seq_group_metadata.sampling_params
          seq_groups.append((seq_ids, sampling_params))
  
          # Use any sequence in the group.
          seq_id = seq_ids[0]
  
          seq_data = seq_group_metadata.seq_data[seq_id]
          prompt_tokens = seq_data.get_token_ids()
          prompt_len = len(prompt_tokens)
          prompt_lens.append(prompt_len)
  
          input_tokens.extend(prompt_tokens)
          # NOTE(woosuk): Here we assume that the first token in the prompt
          # is always the first token in the sequence.
          input_positions.extend(range(len(prompt_tokens)))
  
          # if seq_group_metadata.block_tables is None:
          #     # During memory profiling, the block tables are not initialized
          #     # yet. In this case, we just use a dummy slot mapping.
          #     slot_mapping.extend([0] * prompt_len)
          #     continue
  
          # # Compute the slot mapping.
          # block_table = seq_group_metadata.block_tables[seq_id]
          # for i in range(prompt_len):
          #     block_number = block_table[i // self.block_size]
          #     block_offset = i % self.block_size
          #     slot = block_number * self.block_size + block_offset
          #     slot_mapping.append(slot)
  
      # Add generation tokens.
      max_context_len = 0
      max_num_blocks_per_seq = 0
      context_lens: List[int] = []
      # generation_block_tables: List[List[int]] = []
      for seq_group_metadata in seq_group_metadata_list:
          if seq_group_metadata.is_prompt:
              continue
  
          seq_ids = list(seq_group_metadata.seq_data.keys())
          sampling_params = seq_group_metadata.sampling_params
          seq_groups.append((seq_ids, sampling_params))
  
          for seq_id in seq_ids:
              seq_data = seq_group_metadata.seq_data[seq_id]
              generation_token = seq_data.get_last_token_id()
              input_tokens.append(generation_token)
  
              context_len = seq_data.get_len()
              position = context_len - 1
              if self.sliding_window is not None:
                  context_len = min(context_len, self.sliding_window)
              input_positions.append(position)
  
              # block_table = seq_group_metadata.block_tables[seq_id]
  
              max_context_len = max(max_context_len, context_len)
              # max_num_blocks_per_seq = max(max_num_blocks_per_seq,
              #                              len(block_table))
              context_lens.append(context_len)
  
              # block_number = block_table[position // self.block_size]
              # block_offset = position % self.block_size
              # slot = block_number * self.block_size + block_offset
              # slot_mapping.append(slot)
  
              if self.sliding_window is not None:
                  sliding_window_blocks = (
                      self.sliding_window // self.block_size
                  )
                  block_table = block_table[-sliding_window_blocks:]
              # generation_block_tables.append(block_table)
  
      # Optimization: Pad the input length to be a multiple of 8.
      # This is required for utilizing the Tensor Cores in NVIDIA GPUs.
      input_tokens = _pad_to_alignment(input_tokens, multiple_of=8)
      input_positions = _pad_to_alignment(
          input_positions, multiple_of=8
      )
  
      # Convert to tensors.
      tokens_tensor = torch.tensor(
          input_tokens,
          dtype=torch.long,
          # device="cuda"
      )
      positions_tensor = torch.tensor(
          input_positions,
          dtype=torch.long,
          # device="cuda"
      )
      # slot_mapping_tensor = torch.tensor(slot_mapping,
      #                                    dtype=torch.int,
      #                                    device="cuda")
      context_lens_tensor = torch.tensor(
          context_lens,
          dtype=torch.int,
          # device="cuda"
      )
      # padded_block_tables = [
      #     _pad_to_max(block_table, max_num_blocks_per_seq)
      #     for block_table in generation_block_tables
      # ]
      # block_tables_tensor = torch.tensor(padded_block_tables,
      #                                    dtype=torch.int,
      #                                    device="cuda")
  
      seq_data: Dict[int, SequenceData] = {}
      for seq_group_metadata in seq_group_metadata_list:
          seq_data.update(seq_group_metadata.seq_data)
  
      input_metadata = InputMetadata(
          seq_groups=seq_groups,
          seq_data=seq_data,
          prompt_lens=prompt_lens,
          # slot_mapping=slot_mapping_tensor,
          context_lens=context_lens_tensor,
          max_context_len=max_context_len,
          # block_tables=block_tables_tensor,
          sliding_window=self.sliding_window,
      )
      return tokens_tensor, positions_tensor, input_metadata
  
imports: import os
  from typing import Dict, List, Tuple, Optional
  import torch
  import torch.distributed
  import warnings
  import numpy
  import random
  from bigdl.llm.vllm.config import ModelConfig, SchedulerConfig
  from bigdl.llm.vllm.model_executor.model_loader import get_model
  from bigdl.llm.vllm.model_executor.input_metadata import InputMetadata
  from bigdl.llm.vllm.sampling_params import SamplingParams
  from bigdl.llm.vllm.sequence import SequenceData, SamplerOutput, SequenceGroupMetadata
  from bigdl.llm.utils.common import invalidInputError
  from bigdl.llm.vllm.model_executor.utils import set_random_seed
label_desc: Use image node_id 4 for calling the Worker obj's underlying member method code with example usage: obj._prepare_inputs(seq_group_metadata_list) and returns: tokens_tensor,  positions_tensor,  input_metadata