sentencepiece_bpe.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from typing import Dict, Iterator, List, Optional, Tuple, Union
  2. from tokenizers import AddedToken, Tokenizer, decoders, pre_tokenizers, trainers
  3. from tokenizers.models import BPE
  4. from tokenizers.normalizers import NFKC
  5. from .base_tokenizer import BaseTokenizer
  6. class SentencePieceBPETokenizer(BaseTokenizer):
  7. """SentencePiece BPE Tokenizer
  8. Represents the BPE algorithm, with the pretokenization used by SentencePiece
  9. """
  10. def __init__(
  11. self,
  12. vocab: Optional[Union[str, Dict[str, int]]] = None,
  13. merges: Optional[Union[str, List[Tuple[str, str]]]] = None,
  14. unk_token: Union[str, AddedToken] = "<unk>",
  15. replacement: str = "▁",
  16. add_prefix_space: bool = True,
  17. dropout: Optional[float] = None,
  18. fuse_unk: Optional[bool] = False,
  19. ):
  20. if vocab is not None and merges is not None:
  21. tokenizer = Tokenizer(BPE(vocab, merges, dropout=dropout, unk_token=unk_token, fuse_unk=fuse_unk))
  22. else:
  23. tokenizer = Tokenizer(BPE(dropout=dropout, unk_token=unk_token, fuse_unk=fuse_unk))
  24. if tokenizer.token_to_id(str(unk_token)) is not None:
  25. tokenizer.add_special_tokens([str(unk_token)])
  26. tokenizer.normalizer = NFKC()
  27. prepend_scheme = "always" if add_prefix_space else "never"
  28. tokenizer.pre_tokenizer = pre_tokenizers.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme)
  29. tokenizer.decoder = decoders.Metaspace(replacement=replacement, prepend_scheme=prepend_scheme)
  30. parameters = {
  31. "model": "SentencePieceBPE",
  32. "unk_token": unk_token,
  33. "replacement": replacement,
  34. "add_prefix_space": add_prefix_space,
  35. "dropout": dropout,
  36. }
  37. super().__init__(tokenizer, parameters)
  38. @staticmethod
  39. def from_file(vocab_filename: str, merges_filename: str, **kwargs):
  40. vocab, merges = BPE.read_file(vocab_filename, merges_filename)
  41. return SentencePieceBPETokenizer(vocab, merges, **kwargs)
  42. def train(
  43. self,
  44. files: Union[str, List[str]],
  45. vocab_size: int = 30000,
  46. min_frequency: int = 2,
  47. special_tokens: List[Union[str, AddedToken]] = ["<unk>"],
  48. limit_alphabet: int = 1000,
  49. initial_alphabet: List[str] = [],
  50. show_progress: bool = True,
  51. ):
  52. """Train the model using the given files"""
  53. trainer = trainers.BpeTrainer(
  54. vocab_size=vocab_size,
  55. min_frequency=min_frequency,
  56. special_tokens=special_tokens,
  57. limit_alphabet=limit_alphabet,
  58. initial_alphabet=initial_alphabet,
  59. show_progress=show_progress,
  60. )
  61. if isinstance(files, str):
  62. files = [files]
  63. self._tokenizer.train(files, trainer=trainer)
  64. def train_from_iterator(
  65. self,
  66. iterator: Union[Iterator[str], Iterator[Iterator[str]]],
  67. vocab_size: int = 30000,
  68. min_frequency: int = 2,
  69. special_tokens: List[Union[str, AddedToken]] = ["<unk>"],
  70. limit_alphabet: int = 1000,
  71. initial_alphabet: List[str] = [],
  72. show_progress: bool = True,
  73. length: Optional[int] = None,
  74. ):
  75. """Train the model using the given iterator"""
  76. trainer = trainers.BpeTrainer(
  77. vocab_size=vocab_size,
  78. min_frequency=min_frequency,
  79. special_tokens=special_tokens,
  80. limit_alphabet=limit_alphabet,
  81. initial_alphabet=initial_alphabet,
  82. show_progress=show_progress,
  83. )
  84. self._tokenizer.train_from_iterator(
  85. iterator,
  86. trainer=trainer,
  87. length=length,
  88. )