code: def _update_mems(self, hids, mems, qlen, mlen):
      # does not deal with None
      if mems is None:
          return None
  
      # mems is not None
      assert len(hids) == len(mems), "len(hids) != len(mems)"
  
      # There are `mlen + qlen` steps that can be cached into mems
      # For the next step, the last `ext_len` of the `qlen` tokens
      # will be used as the extended context. Hence, we only cache
      # the tokens from `mlen + qlen - self.ext_len - self.mem_len`
      # to `mlen + qlen - self.ext_len`.
      with torch.no_grad():
          new_mems = []
          end_idx = mlen + max(0, qlen - 0 - self.ext_len)
          beg_idx = max(0, end_idx - self.mem_len)
          for i in range(len(hids)):
              cat = torch.cat([mems[i], hids[i]], dim=0)
              new_mems.append(cat[beg_idx:end_idx].detach())
  
      return new_mems
  
imports: import sys
  import math
  import functools
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from proj_adaptive_softmax import ProjectedAdaptiveLogSoftmax, Projection
  from log_uniform_sampler import LogUniformSampler, sample_logits
  from fmoe import FMoETransformerMLP
label_desc: Use image node_id 6 for calling the MemTransformerLM obj's underlying member method code with example usage: obj._update_mems(hids, mems, qlen, mlen) and returns: new_mems, None