code: def train(dataset, args):
      g = dataset["train-graph"]
      val_matrix = dataset["val-matrix"].tocsr()
      test_matrix = dataset["test-matrix"].tocsr()
      item_texts = dataset["item-texts"]
      user_ntype = dataset["user-type"]
      item_ntype = dataset["item-type"]
      user_to_item_etype = dataset["user-to-item-type"]
      timestamp = dataset["timestamp-edge-column"]
  
      device = torch.device(args.device)
  
      # Assign user and movie IDs and use them as features (to learn an individual trainable
      # embedding for each entity)
      g.nodes[user_ntype].data["id"] = torch.arange(
          g.num_nodes(user_ntype)
      )
      g.nodes[item_ntype].data["id"] = torch.arange(
          g.num_nodes(item_ntype)
      )
  
      # Prepare torchtext dataset and Vocabulary
      textset = {}
      tokenizer = get_tokenizer(None)
  
      textlist = []
      batch_first = True
  
      for i in range(g.num_nodes(item_ntype)):
          for key in item_texts.keys():
              l = tokenizer(item_texts[key][i].lower())
              textlist.append(l)
      for key, field in item_texts.items():
          vocab2 = build_vocab_from_iterator(
              textlist, specials=["<unk>", "<pad>"]
          )
          textset[key] = (
              textlist,
              vocab2,
              vocab2.get_stoi()["<pad>"],
              batch_first,
          )
  
      # Sampler
      batch_sampler = sampler_module.ItemToItemBatchSampler(
          g, user_ntype, item_ntype, args.batch_size
      )
      neighbor_sampler = sampler_module.NeighborSampler(
          g,
          user_ntype,
          item_ntype,
          args.random_walk_length,
          args.random_walk_restart_prob,
          args.num_random_walks,
          args.num_neighbors,
          args.num_layers,
      )
      collator = sampler_module.PinSAGECollator(
          neighbor_sampler, g, item_ntype, textset
      )
      dataloader = DataLoader(
          batch_sampler,
          collate_fn=collator.collate_train,
          num_workers=args.num_workers,
      )
      dataloader_test = DataLoader(
          torch.arange(g.num_nodes(item_ntype)),
          batch_size=args.batch_size,
          collate_fn=collator.collate_test,
          num_workers=args.num_workers,
      )
      dataloader_it = iter(dataloader)
  
      # Model
      model = PinSAGEModel(
          g, item_ntype, textset, args.hidden_dims, args.num_layers
      ).to(device)
      # Optimizer
      opt = torch.optim.Adam(model.parameters(), lr=args.lr)
  
      # For each batch of head-tail-negative triplets...
      for epoch_id in range(args.num_epochs):
          model.train()
          for batch_id in tqdm.trange(args.batches_per_epoch):
              pos_graph, neg_graph, blocks = next(dataloader_it)
              # Copy to GPU
              for i in range(len(blocks)):
                  blocks[i] = blocks[i].to(device)
              pos_graph = pos_graph.to(device)
              neg_graph = neg_graph.to(device)
  
              loss = model(pos_graph, neg_graph, blocks).mean()
              opt.zero_grad()
              loss.backward()
              opt.step()
  
          # Evaluate
          model.eval()
          with torch.no_grad():
              item_batches = torch.arange(
                  g.num_nodes(item_ntype)
              ).split(args.batch_size)
              h_item_batches = []
              for blocks in dataloader_test:
                  for i in range(len(blocks)):
                      blocks[i] = blocks[i].to(device)
  
                  h_item_batches.append(model.get_repr(blocks))
              h_item = torch.cat(h_item_batches, 0)
  
              print(
                  evaluation.evaluate_nn(
                      dataset, h_item, args.k, args.batch_size
                  )
              )
  
imports: import argparse
  import os
  import pickle
  import dgl
  import evaluation
  import layers
  import numpy
  import sampler
  import torch
  import torch.nn
  import torchtext
  import tqdm
  from torch.utils.data import DataLoader
  from torchtext.data.utils import get_tokenizer
  from torchtext.vocab import build_vocab_from_iterator
label_desc: Use image node_id 1 for calling a global function with example usage: train(dataset, args) without return types