code: def test_case4(self):
      # bmes tag
      def _generate_samples():
          target = []
          seq_len = []
          vocab = Vocabulary(unknown=None, padding=None)
          for i in range(3):
              target_i = []
              seq_len_i = 0
              for j in range(1, 10):
                  word_len = np.random.randint(1, 5)
                  seq_len_i += word_len
                  if word_len == 1:
                      target_i.append("S")
                  else:
                      target_i.append("B")
                      target_i.extend(["M"] * (word_len - 2))
                      target_i.append("E")
              vocab.add_word_lst(target_i)
              target.append(target_i)
              seq_len.append(seq_len_i)
          target_ = np.zeros((3, max(seq_len)))
          for i in range(3):
              target_i = [vocab.to_index(t) for t in target[i]]
              target_[i, : seq_len[i]] = target_i
          return target_, target, seq_len, vocab
  
      def get_eval(raw_target, pred, vocab, seq_len):
          pred = pred.argmax(dim=-1).tolist()
          tp = 0
          gold = 0
          seg = 0
          pred_target = []
          for i in range(len(seq_len)):
              tags = [vocab.to_word(p) for p in pred[i][: seq_len[i]]]
              spans = []
              prev_bmes_tag = None
              for idx, tag in enumerate(tags):
                  if tag in ("B", "S"):
                      spans.append([idx, idx])
                  elif tag in ("M", "E") and prev_bmes_tag in (
                      "B",
                      "M",
                  ):
                      spans[-1][1] = idx
                  else:
                      spans.append([idx, idx])
                  prev_bmes_tag = tag
              tmp = []
              for span in spans:
                  if span[1] - span[0] > 0:
                      tmp.extend(
                          ["B"]
                          + ["M"] * (span[1] - span[0] - 1)
                          + ["E"]
                      )
                  else:
                      tmp.append("S")
              pred_target.append(tmp)
          for i in range(len(seq_len)):
              raw_pred = pred_target[i]
              start = 0
              for j in range(seq_len[i]):
                  if raw_target[i][j] in ("E", "S"):
                      flag = True
                      for k in range(start, j + 1):
                          if raw_target[i][k] != raw_pred[k]:
                              flag = False
                              break
                      if flag:
                          tp += 1
                      start = j + 1
                      gold += 1
                  if raw_pred[j] in ("E", "S"):
                      seg += 1
  
          pre = round(tp / seg, 6)
          rec = round(tp / gold, 6)
          return {
              "f": round(2 * pre * rec / (pre + rec), 6),
              "pre": pre,
              "rec": rec,
          }
  
      target, raw_target, seq_len, vocab = _generate_samples()
      pred = torch.randn(3, max(seq_len), 4)
  
      expected_metric = get_eval(raw_target, pred, vocab, seq_len)
      metric = SpanFPreRecMetric(tag_vocab=vocab, encoding_type="bmes")
      metric.update(pred, torch.from_numpy(target), seq_len)
      # print(metric.get_metric(reset=False))
      # print(expected_metric)
      metric_value = metric.get_metric()
      for key, value in expected_metric.items():
          assert np.allclose(value, metric_value[key], 1.0e-4)
  
imports: import pytest
  from collections import Counter
  import os, sys
  import copy
  from functools import partial
  import numpy
  import socket
  from fastNLP.core.vocabulary import Vocabulary
  from fastNLP.core.metrics import SpanFPreRecMetric
  from fastNLP.core.dataset import DataSet
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
  from .utils import find_free_network_port, setup_ddp
label_desc: Use image node_id 4 for calling the TestSpanFPreRecMetric obj's underlying member method code with example usage: obj.test_case4() and returns: target_,  target,  seq_len,  vocab, dict