cui-llama.rn 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +317 -319
  3. package/android/build.gradle +116 -116
  4. package/android/gradle.properties +5 -5
  5. package/android/src/main/AndroidManifest.xml +4 -4
  6. package/android/src/main/CMakeLists.txt +124 -124
  7. package/android/src/main/java/com/rnllama/LlamaContext.java +645 -645
  8. package/android/src/main/java/com/rnllama/RNLlama.java +695 -695
  9. package/android/src/main/java/com/rnllama/RNLlamaPackage.java +48 -48
  10. package/android/src/main/jni-utils.h +100 -100
  11. package/android/src/main/jni.cpp +1263 -1263
  12. package/android/src/main/jniLibs/arm64-v8a/librnllama.so +0 -0
  13. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8.so +0 -0
  14. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2.so +0 -0
  15. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod.so +0 -0
  16. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod_i8mm.so +0 -0
  17. package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_i8mm.so +0 -0
  18. package/android/src/main/jniLibs/x86_64/librnllama.so +0 -0
  19. package/android/src/main/jniLibs/x86_64/librnllama_x86_64.so +0 -0
  20. package/android/src/newarch/java/com/rnllama/RNLlamaModule.java +135 -135
  21. package/android/src/oldarch/java/com/rnllama/RNLlamaModule.java +136 -136
  22. package/cpp/README.md +4 -4
  23. package/cpp/ggml-llama-sim.metallib +0 -0
  24. package/cpp/ggml-llama.metallib +0 -0
  25. package/cpp/ggml-metal-impl.h +597 -597
  26. package/cpp/ggml-metal.m +4 -0
  27. package/cpp/ggml.h +1 -1
  28. package/cpp/rn-llama.cpp +873 -873
  29. package/cpp/rn-llama.h +138 -138
  30. package/cpp/sampling.h +107 -107
  31. package/cpp/unicode-data.cpp +7034 -7034
  32. package/cpp/unicode-data.h +20 -20
  33. package/cpp/unicode.cpp +849 -849
  34. package/cpp/unicode.h +66 -66
  35. package/ios/CMakeLists.txt +116 -108
  36. package/ios/RNLlama.h +7 -7
  37. package/ios/RNLlama.mm +418 -405
  38. package/ios/RNLlamaContext.h +57 -57
  39. package/ios/RNLlamaContext.mm +835 -835
  40. package/ios/rnllama.xcframework/Info.plist +74 -74
  41. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/binary-ops.h +16 -0
  42. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/chat.h +143 -0
  43. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/common.h +677 -0
  44. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/cpu-common.h +72 -0
  45. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-alloc.h +76 -0
  46. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  47. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-backend.h +354 -0
  48. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-common.h +1857 -0
  49. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpp.h +39 -0
  50. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  51. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  52. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  53. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  54. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-cpu.h +138 -0
  55. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-impl.h +594 -0
  56. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  57. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-metal.h +66 -0
  58. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-opt.h +216 -0
  59. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-quants.h +100 -0
  60. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml-threading.h +14 -0
  61. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ggml.h +2222 -0
  62. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/gguf.h +202 -0
  63. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  64. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/json.hpp +24766 -0
  65. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-adapter.h +76 -0
  66. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-arch.h +428 -0
  67. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-batch.h +88 -0
  68. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-chat.h +56 -0
  69. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-context.h +265 -0
  70. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-cparams.h +38 -0
  71. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-cpp.h +30 -0
  72. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-grammar.h +173 -0
  73. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-graph.h +592 -0
  74. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-hparams.h +156 -0
  75. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-impl.h +61 -0
  76. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-io.h +35 -0
  77. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  78. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-memory.h +21 -0
  79. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-mmap.h +68 -0
  80. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-model-loader.h +169 -0
  81. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-model.h +409 -0
  82. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-sampling.h +32 -0
  83. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama-vocab.h +125 -0
  84. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/llama.h +1434 -0
  85. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/log.h +132 -0
  86. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  87. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  88. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/ops.h +128 -0
  89. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/rn-llama.h +138 -0
  90. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/sampling.h +107 -0
  91. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/sgemm.h +14 -0
  92. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/simd-mappings.h +888 -0
  93. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/speculative.h +28 -0
  94. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unary-ops.h +28 -0
  95. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unicode-data.h +20 -0
  96. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/unicode.h +66 -0
  97. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Headers/vec.h +802 -0
  98. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/Info.plist +0 -0
  99. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/ggml-llama.metallib +0 -0
  100. package/ios/rnllama.xcframework/ios-arm64/rnllama.framework/rnllama +0 -0
  101. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/binary-ops.h +16 -0
  102. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/chat.h +143 -0
  103. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/common.h +677 -0
  104. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/cpu-common.h +72 -0
  105. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-alloc.h +76 -0
  106. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  107. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend.h +354 -0
  108. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-common.h +1857 -0
  109. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpp.h +39 -0
  110. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  111. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  112. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  113. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  114. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu.h +138 -0
  115. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-impl.h +594 -0
  116. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  117. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal.h +66 -0
  118. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-opt.h +216 -0
  119. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-quants.h +100 -0
  120. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-threading.h +14 -0
  121. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ggml.h +2222 -0
  122. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/gguf.h +202 -0
  123. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  124. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/json.hpp +24766 -0
  125. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-adapter.h +76 -0
  126. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-arch.h +428 -0
  127. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-batch.h +88 -0
  128. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-chat.h +56 -0
  129. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-context.h +265 -0
  130. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cparams.h +38 -0
  131. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cpp.h +30 -0
  132. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-grammar.h +173 -0
  133. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-graph.h +592 -0
  134. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-hparams.h +156 -0
  135. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-impl.h +61 -0
  136. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-io.h +35 -0
  137. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  138. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-memory.h +21 -0
  139. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-mmap.h +68 -0
  140. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model-loader.h +169 -0
  141. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model.h +409 -0
  142. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-sampling.h +32 -0
  143. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama-vocab.h +125 -0
  144. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/llama.h +1434 -0
  145. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/log.h +132 -0
  146. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  147. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  148. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/ops.h +128 -0
  149. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/rn-llama.h +138 -0
  150. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/sampling.h +107 -0
  151. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/sgemm.h +14 -0
  152. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/simd-mappings.h +888 -0
  153. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/speculative.h +28 -0
  154. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unary-ops.h +28 -0
  155. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unicode-data.h +20 -0
  156. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/unicode.h +66 -0
  157. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Headers/vec.h +802 -0
  158. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/Info.plist +0 -0
  159. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/_CodeSignature/CodeResources +101 -0
  160. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/ggml-llama-sim.metallib +0 -0
  161. package/ios/rnllama.xcframework/ios-arm64_x86_64-simulator/rnllama.framework/rnllama +0 -0
  162. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/binary-ops.h +16 -0
  163. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/chat.h +143 -0
  164. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/common.h +677 -0
  165. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/cpu-common.h +72 -0
  166. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-alloc.h +76 -0
  167. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  168. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-backend.h +354 -0
  169. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-common.h +1857 -0
  170. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpp.h +39 -0
  171. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  172. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  173. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  174. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  175. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-cpu.h +138 -0
  176. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-impl.h +594 -0
  177. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  178. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-metal.h +66 -0
  179. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-opt.h +216 -0
  180. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-quants.h +100 -0
  181. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml-threading.h +14 -0
  182. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ggml.h +2222 -0
  183. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/gguf.h +202 -0
  184. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  185. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/json.hpp +24766 -0
  186. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-adapter.h +76 -0
  187. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-arch.h +428 -0
  188. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-batch.h +88 -0
  189. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-chat.h +56 -0
  190. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-context.h +265 -0
  191. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-cparams.h +38 -0
  192. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-cpp.h +30 -0
  193. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-grammar.h +173 -0
  194. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-graph.h +592 -0
  195. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-hparams.h +156 -0
  196. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-impl.h +61 -0
  197. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-io.h +35 -0
  198. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  199. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-memory.h +21 -0
  200. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-mmap.h +68 -0
  201. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-model-loader.h +169 -0
  202. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-model.h +409 -0
  203. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-sampling.h +32 -0
  204. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama-vocab.h +125 -0
  205. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/llama.h +1434 -0
  206. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/log.h +132 -0
  207. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  208. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  209. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/ops.h +128 -0
  210. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/rn-llama.h +138 -0
  211. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/sampling.h +107 -0
  212. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/sgemm.h +14 -0
  213. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/simd-mappings.h +888 -0
  214. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/speculative.h +28 -0
  215. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unary-ops.h +28 -0
  216. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unicode-data.h +20 -0
  217. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/unicode.h +66 -0
  218. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Headers/vec.h +802 -0
  219. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/Info.plist +0 -0
  220. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/ggml-llama.metallib +0 -0
  221. package/ios/rnllama.xcframework/tvos-arm64/rnllama.framework/rnllama +0 -0
  222. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/binary-ops.h +16 -0
  223. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/chat.h +143 -0
  224. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/common.h +677 -0
  225. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/cpu-common.h +72 -0
  226. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-alloc.h +76 -0
  227. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend-impl.h +255 -0
  228. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-backend.h +354 -0
  229. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-common.h +1857 -0
  230. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpp.h +39 -0
  231. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-aarch64.h +8 -0
  232. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-impl.h +512 -0
  233. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-quants.h +63 -0
  234. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu-traits.h +38 -0
  235. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-cpu.h +138 -0
  236. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-impl.h +594 -0
  237. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal-impl.h +597 -0
  238. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-metal.h +66 -0
  239. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-opt.h +216 -0
  240. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-quants.h +100 -0
  241. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml-threading.h +14 -0
  242. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ggml.h +2222 -0
  243. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/gguf.h +202 -0
  244. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/json-schema-to-grammar.h +21 -0
  245. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/json.hpp +24766 -0
  246. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-adapter.h +76 -0
  247. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-arch.h +428 -0
  248. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-batch.h +88 -0
  249. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-chat.h +56 -0
  250. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-context.h +265 -0
  251. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cparams.h +38 -0
  252. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-cpp.h +30 -0
  253. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-grammar.h +173 -0
  254. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-graph.h +592 -0
  255. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-hparams.h +156 -0
  256. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-impl.h +61 -0
  257. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-io.h +35 -0
  258. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-kv-cache.h +213 -0
  259. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-memory.h +21 -0
  260. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-mmap.h +68 -0
  261. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model-loader.h +169 -0
  262. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-model.h +409 -0
  263. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-sampling.h +32 -0
  264. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama-vocab.h +125 -0
  265. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/llama.h +1434 -0
  266. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/log.h +132 -0
  267. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/minja/chat-template.hpp +537 -0
  268. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/minja/minja.hpp +2941 -0
  269. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/ops.h +128 -0
  270. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/rn-llama.h +138 -0
  271. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/sampling.h +107 -0
  272. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/sgemm.h +14 -0
  273. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/simd-mappings.h +888 -0
  274. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/speculative.h +28 -0
  275. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unary-ops.h +28 -0
  276. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unicode-data.h +20 -0
  277. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/unicode.h +66 -0
  278. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Headers/vec.h +802 -0
  279. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/Info.plist +0 -0
  280. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/_CodeSignature/CodeResources +101 -0
  281. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/ggml-llama-sim.metallib +0 -0
  282. package/ios/rnllama.xcframework/tvos-arm64_x86_64-simulator/rnllama.framework/rnllama +0 -0
  283. package/jest/mock.js +203 -203
  284. package/lib/commonjs/NativeRNLlama.js +1 -2
  285. package/lib/commonjs/NativeRNLlama.js.map +1 -1
  286. package/lib/commonjs/chat.js.map +1 -1
  287. package/lib/commonjs/grammar.js +12 -31
  288. package/lib/commonjs/grammar.js.map +1 -1
  289. package/lib/commonjs/index.js +47 -47
  290. package/lib/commonjs/index.js.map +1 -1
  291. package/lib/commonjs/package.json +1 -0
  292. package/lib/module/NativeRNLlama.js +2 -0
  293. package/lib/module/NativeRNLlama.js.map +1 -1
  294. package/lib/module/chat.js +2 -0
  295. package/lib/module/chat.js.map +1 -1
  296. package/lib/module/grammar.js +14 -31
  297. package/lib/module/grammar.js.map +1 -1
  298. package/lib/module/index.js +47 -45
  299. package/lib/module/index.js.map +1 -1
  300. package/lib/module/package.json +1 -0
  301. package/lib/typescript/NativeRNLlama.d.ts +6 -4
  302. package/lib/typescript/NativeRNLlama.d.ts.map +1 -1
  303. package/lib/typescript/index.d.ts.map +1 -1
  304. package/llama-rn.podspec +48 -48
  305. package/package.json +233 -233
  306. package/src/NativeRNLlama.ts +426 -426
  307. package/src/chat.ts +44 -44
  308. package/src/grammar.ts +854 -854
  309. package/src/index.ts +495 -487
package/cpp/unicode.cpp CHANGED
@@ -1,849 +1,849 @@
1
- #if defined(_MSC_VER)
2
- #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
3
- #endif
4
-
5
- #include "unicode.h"
6
- #include "unicode-data.h"
7
-
8
- #include <algorithm>
9
- #include <cassert>
10
- #include <codecvt>
11
- #include <cstddef>
12
- #include <cstdint>
13
- #include <locale>
14
- #include <map>
15
- #include <regex>
16
- #include <stdexcept>
17
- #include <string>
18
- #include <unordered_map>
19
- #include <utility>
20
- #include <vector>
21
-
22
- size_t unicode_len_utf8(char src) {
23
- const size_t lookup[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4 };
24
- uint8_t highbits = static_cast<uint8_t>(src) >> 4;
25
- return lookup[highbits];
26
- }
27
-
28
- static std::string unicode_cpts_to_utf8(const std::vector<uint32_t> & cps) {
29
- std::string result;
30
- for (size_t i = 0; i < cps.size(); ++i) {
31
- result.append(unicode_cpt_to_utf8(cps[i]));
32
- }
33
- return result;
34
- }
35
-
36
- uint32_t unicode_cpt_from_utf8(const std::string & utf8, size_t & offset) {
37
- assert(offset < utf8.size());
38
- if (!(utf8[offset + 0] & 0x80)) {
39
- auto result = utf8[offset + 0];
40
- offset += 1;
41
- return result;
42
- }
43
- if (!(utf8[offset + 0] & 0x40)) {
44
- throw std::invalid_argument("invalid character");
45
- }
46
- if (!(utf8[offset + 0] & 0x20)) {
47
- if (offset + 1 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80)) {
48
- throw std::invalid_argument("invalid character");
49
- }
50
- auto result = ((utf8[offset + 0] & 0x1f) << 6) | (utf8[offset + 1] & 0x3f);
51
- offset += 2;
52
- return result;
53
- }
54
- if (!(utf8[offset + 0] & 0x10)) {
55
- if (offset + 2 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80) || ! ((utf8[offset + 2] & 0xc0) == 0x80)) {
56
- throw std::invalid_argument("invalid character");
57
- }
58
- auto result = ((utf8[offset + 0] & 0x0f) << 12) | ((utf8[offset + 1] & 0x3f) << 6) | (utf8[offset + 2] & 0x3f);
59
- offset += 3;
60
- return result;
61
- }
62
- if (!(utf8[offset + 0] & 0x08)) {
63
- if (offset + 3 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80) || ! ((utf8[offset + 2] & 0xc0) == 0x80) || !((utf8[offset + 3] & 0xc0) == 0x80)) {
64
- throw std::invalid_argument("invalid character");
65
- }
66
- auto result = ((utf8[offset + 0] & 0x07) << 18) | ((utf8[offset + 1] & 0x3f) << 12) | ((utf8[offset + 2] & 0x3f) << 6) | (utf8[offset + 3] & 0x3f);
67
- offset += 4;
68
- return result;
69
- }
70
- throw std::invalid_argument("failed to convert utf8 to codepoint");
71
- }
72
-
73
- //static std::vector<uint16_t> unicode_cpt_to_utf16(uint32_t cpt) {
74
- // std::vector<uint16_t> result;
75
- // if (/* 0x0000 <= cpt && */ cpt <= 0xffff) {
76
- // result.emplace_back(cpt);
77
- // return result;
78
- // }
79
- // if (0x10000 <= cpt && cpt <= 0x10ffff) {
80
- // result.emplace_back(0xd800 | ((cpt - 0x10000) >> 10));
81
- // result.emplace_back(0xdc00 | ((cpt - 0x10000) & 0x03ff));
82
- // return result;
83
- // }
84
- // throw std::invalid_argument("failed to convert codepoint to utf16");
85
- //}
86
-
87
- //static std::vector<uint16_t> unicode_cpts_to_utf16(const std::vector<uint32_t> & cps) {
88
- // std::vector<uint16_t> result;
89
- // for (size_t i = 0; i < cps.size(); ++i) {
90
- // auto temp = unicode_cpt_to_utf16(cps[i]);
91
- // result.insert(result.end(), temp.begin(), temp.end());
92
- // }
93
- // return result;
94
- //}
95
-
96
- //static uint32_t unicode_cpt_from_utf16(const std::vector<uint16_t> & utf16, size_t & offset) {
97
- // assert(offset < utf16.size());
98
- // if (((utf16[0] >> 10) << 10) != 0xd800) {
99
- // auto result = utf16[offset + 0];
100
- // offset += 1;
101
- // return result;
102
- // }
103
- //
104
- // if (offset + 1 >= utf16.size() || !((utf16[1] & 0xdc00) == 0xdc00)) {
105
- // throw std::invalid_argument("invalid character");
106
- // }
107
- //
108
- // auto result = 0x10000 + (((utf16[0] & 0x03ff) << 10) | (utf16[1] & 0x03ff));
109
- // offset += 2;
110
- // return result;
111
- //}
112
-
113
- //static std::vector<uint32_t> unicode_cpts_from_utf16(const std::vector<uint16_t> & utf16) {
114
- // std::vector<uint32_t> result;
115
- // size_t offset = 0;
116
- // while (offset < utf16.size()) {
117
- // result.push_back(unicode_cpt_from_utf16(utf16, offset));
118
- // }
119
- // return result;
120
- //}
121
-
122
- static std::vector<unicode_cpt_flags> unicode_cpt_flags_array() {
123
- std::vector<unicode_cpt_flags> cpt_flags(MAX_CODEPOINTS, unicode_cpt_flags::UNDEFINED);
124
-
125
- assert (unicode_ranges_flags.begin()[0].first == 0);
126
- assert (unicode_ranges_flags.begin()[unicode_ranges_flags.size()-1].first == MAX_CODEPOINTS);
127
- for (size_t i = 1; i < unicode_ranges_flags.size(); ++i) {
128
- const auto range_ini = unicode_ranges_flags.begin()[i-1]; // codepoint_ini, flags
129
- const auto range_end = unicode_ranges_flags.begin()[i]; // codepoint_end, flags
130
- for (uint32_t cpt = range_ini.first; cpt < range_end.first; ++cpt) {
131
- cpt_flags[cpt] = range_ini.second;
132
- }
133
- }
134
-
135
- for (auto cpt : unicode_set_whitespace) {
136
- cpt_flags[cpt].is_whitespace = true;
137
- }
138
-
139
- for (auto p : unicode_map_lowercase) {
140
- cpt_flags[p.second].is_lowercase = true;
141
- }
142
-
143
- for (auto p : unicode_map_uppercase) {
144
- cpt_flags[p.second].is_uppercase = true;
145
- }
146
-
147
- for (auto &range : unicode_ranges_nfd) { // start, last, nfd
148
- cpt_flags[range.nfd].is_nfd = true;
149
- }
150
-
151
- return cpt_flags;
152
- }
153
-
154
- static std::unordered_map<uint8_t, std::string> unicode_byte_to_utf8_map() {
155
- std::unordered_map<uint8_t, std::string> map;
156
- for (int ch = 0x21; ch <= 0x7E; ++ch) { // u'!' to u'~'
157
- assert(0 <= ch && ch < 256);
158
- map[ch] = unicode_cpt_to_utf8(ch);
159
- }
160
- for (int ch = 0xA1; ch <= 0xAC; ++ch) { // u'¡' to u'¬'
161
- assert(0 <= ch && ch < 256);
162
- map[ch] = unicode_cpt_to_utf8(ch);
163
- }
164
- for (int ch = 0xAE; ch <= 0xFF; ++ch) { // u'®' to u'ÿ'
165
- assert(0 <= ch && ch < 256);
166
- map[ch] = unicode_cpt_to_utf8(ch);
167
- }
168
- auto n = 0;
169
- for (int ch = 0; ch < 256; ++ch) {
170
- if (map.find(ch) == map.end()) {
171
- map[ch] = unicode_cpt_to_utf8(256 + n);
172
- ++n;
173
- }
174
- }
175
- return map;
176
- }
177
-
178
- static std::unordered_map<std::string, uint8_t> unicode_utf8_to_byte_map() {
179
- std::unordered_map<std::string, uint8_t> map;
180
- for (int ch = 0x21; ch <= 0x7E; ++ch) { // u'!' to u'~'
181
- assert(0 <= ch && ch < 256);
182
- map[unicode_cpt_to_utf8(ch)] = ch;
183
- }
184
- for (int ch = 0xA1; ch <= 0xAC; ++ch) { // u'¡' to u'¬'
185
- assert(0 <= ch && ch < 256);
186
- map[unicode_cpt_to_utf8(ch)] = ch;
187
- }
188
- for (int ch = 0xAE; ch <= 0xFF; ++ch) { // u'®' to u'ÿ'
189
- assert(0 <= ch && ch < 256);
190
- map[unicode_cpt_to_utf8(ch)] = ch;
191
- }
192
- auto n = 0;
193
- for (int ch = 0; ch < 256; ++ch) {
194
- if (map.find(unicode_cpt_to_utf8(ch)) == map.end()) {
195
- map[unicode_cpt_to_utf8(256 + n)] = ch;
196
- ++n;
197
- }
198
- }
199
- return map;
200
- }
201
-
202
- static inline std::wstring unicode_wstring_from_utf8(const std::string & s) {
203
- #if defined(__clang__)
204
- // disable C++17 deprecation warning for std::codecvt_utf8
205
- # pragma clang diagnostic push
206
- # pragma clang diagnostic ignored "-Wdeprecated-declarations"
207
- #endif
208
-
209
- std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
210
-
211
- #if defined(__clang__)
212
- # pragma clang diagnostic pop
213
- #endif
214
-
215
- return conv.from_bytes(s);
216
- }
217
-
218
- static std::vector<std::string> unicode_byte_encoding_process(const std::vector<std::string> & bpe_words) {
219
- std::vector<std::string> bpe_encoded_words;
220
- for (const auto & word : bpe_words) {
221
- std::string text_utf;
222
- auto utf_word = unicode_cpts_from_utf8(word);
223
- for (size_t i = 0; i < utf_word.size(); ++i) {
224
- text_utf += unicode_cpt_to_utf8(utf_word[i]);
225
- }
226
-
227
- std::string encoded_token;
228
- for (char & c : text_utf) {
229
- encoded_token += unicode_byte_to_utf8(c);
230
- }
231
- bpe_encoded_words.emplace_back(encoded_token);
232
- }
233
- return bpe_encoded_words;
234
- }
235
-
236
- // GPT2 system regex: 's|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+
237
- static std::vector<size_t> unicode_regex_split_custom_gpt2(const std::string & text, const std::vector<size_t> & offsets) {
238
- std::vector<size_t> bpe_offsets; // store the offset of each word
239
- bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
240
-
241
- const auto cpts = unicode_cpts_from_utf8(text);
242
-
243
- size_t start = 0;
244
- for (auto offset : offsets) {
245
- const size_t offset_ini = start;
246
- const size_t offset_end = start + offset;
247
- assert(offset_end <= cpts.size());
248
- start = offset_end;
249
-
250
- static const uint32_t OUT_OF_RANGE = 0xFFFFFFFF;
251
- auto _get_cpt = [&] (const size_t pos) -> uint32_t {
252
- return (offset_ini <= pos && pos < offset_end) ? cpts[pos] : OUT_OF_RANGE;
253
- };
254
-
255
- auto _get_flags = [&] (const size_t pos) -> unicode_cpt_flags {
256
- return (offset_ini <= pos && pos < offset_end) ? unicode_cpt_flags_from_cpt(cpts[pos]) : unicode_cpt_flags{};
257
- };
258
-
259
- size_t _prev_end = offset_ini;
260
- auto _add_token = [&] (const size_t end) -> size_t {
261
- assert(_prev_end <= end && end <= offset_end);
262
- size_t len = end - _prev_end;
263
- if (len > 0) {
264
- bpe_offsets.push_back(len);
265
- }
266
- _prev_end = end;
267
- //if (len > 0) {
268
- // std::string s = "";
269
- // for(size_t p = end-len; p < end; p++)
270
- // s += unicode_cpt_to_utf8(cpts[p]);
271
- // printf(">>> '%s'\n", s.c_str());
272
- //}
273
- return len;
274
- };
275
-
276
- for (size_t pos = offset_ini; pos < offset_end; /*pos++*/ ) {
277
- const uint32_t cpt = _get_cpt(pos);
278
- const auto flags = _get_flags(pos);
279
-
280
- // regex: 's|'t|'re|'ve|'m|'ll|'d
281
- if (cpt == '\'' && pos+1 < offset_end) {
282
- uint32_t cpt_next = _get_cpt(pos+1);
283
- if (cpt_next == 's' || cpt_next == 't' || cpt_next == 'm' || cpt_next == 'd') {
284
- pos += _add_token(pos+2);
285
- continue;
286
- }
287
- if (pos+2 < offset_end) {
288
- uint32_t cpt_next_next = _get_cpt(pos+2);
289
- if ((cpt_next == 'r' && cpt_next_next == 'e') ||
290
- (cpt_next == 'v' && cpt_next_next == 'e') ||
291
- (cpt_next == 'l' && cpt_next_next == 'l')) {
292
- pos += _add_token(pos+3);
293
- continue;
294
- }
295
- }
296
- }
297
-
298
- auto flags2 = (cpt == ' ' ? _get_flags(pos+1) : flags);
299
- // regex: <space>?\p{L}+
300
- if (flags2.is_letter) {
301
- pos += (cpt == ' ');
302
- while (flags2.is_letter) {
303
- flags2 = _get_flags(++pos);
304
- }
305
- _add_token(pos);
306
- continue;
307
- }
308
- // regex: <space>?\p{N}+
309
- if (flags2.is_number) {
310
- pos += (cpt == ' ');
311
- while (flags2.is_number) {
312
- flags2 = _get_flags(++pos);
313
- }
314
- _add_token(pos);
315
- continue;
316
- }
317
- // regex: <space>?[^\s\p{L}\p{N}]+
318
- if (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
319
- pos += (cpt == ' ');
320
- while (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
321
- flags2 = _get_flags(++pos);
322
- }
323
- _add_token(pos);
324
- continue;
325
- }
326
-
327
- size_t num_whitespaces = 0;
328
- while (_get_flags(pos+num_whitespaces).is_whitespace) {
329
- num_whitespaces++;
330
- }
331
-
332
- // regex: \s+(?!\S)
333
- if (num_whitespaces > 1 && _get_cpt(pos+num_whitespaces) != OUT_OF_RANGE) {
334
- pos += num_whitespaces - 1;
335
- _add_token(pos);
336
- continue;
337
- }
338
-
339
- // regex: \s+
340
- if (num_whitespaces > 0) {
341
- pos += num_whitespaces;
342
- _add_token(pos);
343
- continue;
344
- }
345
-
346
- // no matches
347
- _add_token(++pos);
348
- }
349
- }
350
-
351
- return bpe_offsets;
352
- }
353
-
354
- // LLAMA3 system regex: "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+"
355
- static std::vector<size_t> unicode_regex_split_custom_llama3(const std::string & text, const std::vector<size_t> & offsets) {
356
- std::vector<size_t> bpe_offsets; // store the offset of each word
357
- bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
358
-
359
- const auto cpts = unicode_cpts_from_utf8(text);
360
-
361
- size_t start = 0;
362
- for (auto offset : offsets) {
363
- const size_t offset_ini = start;
364
- const size_t offset_end = start + offset;
365
- assert(offset_end <= cpts.size());
366
- start = offset_end;
367
-
368
- static const uint32_t OUT_OF_RANGE = 0xFFFFFFFF;
369
- auto _get_cpt = [&] (const size_t pos) -> uint32_t {
370
- return (offset_ini <= pos && pos < offset_end) ? cpts[pos] : OUT_OF_RANGE;
371
- };
372
-
373
- auto _get_flags = [&] (const size_t pos) -> unicode_cpt_flags {
374
- return (offset_ini <= pos && pos < offset_end) ? unicode_cpt_flags_from_cpt(cpts[pos]) : unicode_cpt_flags{};
375
- };
376
-
377
- size_t _prev_end = offset_ini;
378
- auto _add_token = [&] (const size_t end) -> size_t {
379
- assert(_prev_end <= end && end <= offset_end);
380
- size_t len = end - _prev_end;
381
- if (len > 0) {
382
- bpe_offsets.push_back(len);
383
- }
384
- _prev_end = end;
385
- //if (len > 0) {
386
- // std::string s = "";
387
- // for(size_t p = end-len; p < end; p++)
388
- // s += unicode_cpt_to_utf8(cpts[p]);
389
- // printf(">>> '%s'\n", s.c_str());
390
- //}
391
- return len;
392
- };
393
-
394
- for (size_t pos = offset_ini; pos < offset_end; /*pos++*/ ) {
395
- const uint32_t cpt = _get_cpt(pos);
396
- const auto flags = _get_flags(pos);
397
-
398
- // regex: (?i:'s|'t|'re|'ve|'m|'ll|'d) // case insensitive
399
- if (cpt == '\'' && pos+1 < offset_end) {
400
- uint32_t cpt_next = unicode_tolower(_get_cpt(pos+1));
401
- if (cpt_next == 's' || cpt_next == 't' || cpt_next == 'm' || cpt_next == 'd') {
402
- pos += _add_token(pos+2);
403
- continue;
404
- }
405
- if (pos+2 < offset_end) {
406
- uint32_t cpt_next_next = unicode_tolower(_get_cpt(pos+2));
407
- if ((cpt_next == 'r' && cpt_next_next == 'e') ||
408
- (cpt_next == 'v' && cpt_next_next == 'e') ||
409
- (cpt_next == 'l' && cpt_next_next == 'l')) {
410
- pos += _add_token(pos+3);
411
- continue;
412
- }
413
- }
414
- }
415
-
416
- // regex: [^\r\n\p{L}\p{N}]?\p{L}+
417
- if (!(cpt == '\r' || cpt == '\n' || flags.is_number)) {
418
- if (flags.is_letter || _get_flags(pos+1).is_letter) { // one or more letters
419
- pos++;
420
- while (_get_flags(pos).is_letter) {
421
- pos++;
422
- }
423
- _add_token(pos);
424
- continue;
425
- }
426
- }
427
-
428
- // regex: \p{N}{1,3}
429
- if (flags.is_number) {
430
- size_t ini = pos;
431
- while (_get_flags(pos).is_number) {
432
- if (++pos - ini >= 3 ) {
433
- _add_token(pos);
434
- ini = pos;
435
- }
436
- }
437
- _add_token(pos);
438
- continue;
439
- }
440
-
441
- // regex: <space>?[^\s\p{L}\p{N}]+[\r\n]*
442
- auto flags2 = (cpt == ' ' ? _get_flags(pos+1) : flags);
443
- if (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags.as_uint()) {
444
- pos += (cpt == ' ');
445
- while (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
446
- flags2 = _get_flags(++pos);
447
- }
448
- uint32_t cpt2 = _get_cpt(pos);
449
- while (cpt2 == '\r' || cpt2 == '\n') {
450
- cpt2 = _get_cpt(++pos);
451
- }
452
- _add_token(pos);
453
- continue;
454
- }
455
-
456
- size_t num_whitespaces = 0;
457
- size_t last_end_r_or_n = 0;
458
- while (_get_flags(pos+num_whitespaces).is_whitespace) {
459
- uint32_t cpt2 = _get_cpt(pos+num_whitespaces);
460
- if (cpt2 == '\r' || cpt2 == '\n') {
461
- last_end_r_or_n = pos + num_whitespaces + 1;
462
- }
463
- num_whitespaces++;
464
- }
465
-
466
- // regex: \s*[\r\n]+
467
- if (last_end_r_or_n > 0) {
468
- pos = last_end_r_or_n;
469
- _add_token(pos);
470
- continue;
471
- }
472
-
473
- // regex: \s+(?!\S)
474
- if (num_whitespaces > 1 && _get_cpt(pos+num_whitespaces) != OUT_OF_RANGE) {
475
- pos += num_whitespaces - 1;
476
- _add_token(pos);
477
- continue;
478
- }
479
-
480
- // regex: \s+
481
- if (num_whitespaces > 0) {
482
- pos += num_whitespaces;
483
- _add_token(pos);
484
- continue;
485
- }
486
-
487
- // no matches
488
- _add_token(++pos);
489
- }
490
- }
491
-
492
- return bpe_offsets;
493
- }
494
-
495
- // use std::wregex to split the text
496
- static std::vector<size_t> unicode_regex_split_stl(const std::wstring & wtext, const std::wstring & regex_expr, const std::vector<size_t> & offsets) {
497
- std::wregex expr(regex_expr);
498
- std::vector<size_t> bpe_offsets; // store the offset of each word
499
- bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
500
- size_t start = 0;
501
- for (auto offset : offsets) {
502
- std::wcregex_iterator it(wtext.data() + start, wtext.data() + start + offset, expr);
503
- std::wcregex_iterator end;
504
-
505
- int64_t start_idx = 0;
506
- while (it != end) {
507
- std::wcmatch match = *it;
508
- if (match.position() > start_idx) {
509
- bpe_offsets.emplace_back(match.position() - start_idx);
510
- }
511
- bpe_offsets.emplace_back(match.length());
512
- start_idx = match.position() + match.length();
513
- ++it;
514
- }
515
-
516
- if (start_idx < (int64_t) offset) {
517
- bpe_offsets.emplace_back(offset - start_idx);
518
- }
519
- start += offset;
520
- }
521
-
522
- return bpe_offsets;
523
- }
524
-
525
- // use std::regex to split the text
526
- static std::vector<size_t> unicode_regex_split_stl(const std::string & text, const std::string & regex_expr, const std::vector<size_t> & offsets) {
527
- std::regex expr(regex_expr);
528
- std::vector<size_t> bpe_offsets; // store the offset of each word
529
- bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
530
- size_t start = 0;
531
- for (auto offset : offsets) {
532
- std::cregex_iterator it(text.data() + start, text.data() + start + offset, expr);
533
- std::cregex_iterator end;
534
-
535
- int64_t start_idx = 0;
536
- while (it != end) {
537
- std::cmatch match = *it;
538
- if (match.position() > start_idx) {
539
- bpe_offsets.emplace_back(match.position() - start_idx);
540
- }
541
- bpe_offsets.emplace_back(match.length());
542
- start_idx = match.position() + match.length();
543
- ++it;
544
- }
545
-
546
- if (start_idx < (int64_t) offset) {
547
- bpe_offsets.emplace_back(offset - start_idx);
548
- }
549
- start += offset;
550
- }
551
-
552
- return bpe_offsets;
553
- }
554
-
555
- static std::vector<size_t> unicode_regex_split_custom(const std::string & text, const std::string & regex_expr, const std::vector<size_t> & offsets) {
556
- std::vector<size_t> bpe_offsets;
557
-
558
- if (regex_expr == "'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)") {
559
- bpe_offsets = unicode_regex_split_custom_gpt2(text, offsets);
560
- } else if (
561
- regex_expr == "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?\\p{L}+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+" ||
562
- regex_expr == "(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])|[^\\r\\n\\p{L}\\p{N}]?\\p{L}+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+") {
563
-
564
- bpe_offsets = unicode_regex_split_custom_llama3(text, offsets);
565
- }
566
-
567
- return bpe_offsets;
568
- }
569
-
570
- //
571
- // interface
572
- //
573
-
574
- std::string unicode_cpt_to_utf8(uint32_t cpt) {
575
- std::string result;
576
-
577
- if (/* 0x00 <= cpt && */ cpt <= 0x7f) {
578
- result.push_back(cpt);
579
- return result;
580
- }
581
- if (0x80 <= cpt && cpt <= 0x7ff) {
582
- result.push_back(0xc0 | ((cpt >> 6) & 0x1f));
583
- result.push_back(0x80 | (cpt & 0x3f));
584
- return result;
585
- }
586
- if (0x800 <= cpt && cpt <= 0xffff) {
587
- result.push_back(0xe0 | ((cpt >> 12) & 0x0f));
588
- result.push_back(0x80 | ((cpt >> 6) & 0x3f));
589
- result.push_back(0x80 | (cpt & 0x3f));
590
- return result;
591
- }
592
- if (0x10000 <= cpt && cpt <= 0x10ffff) {
593
- result.push_back(0xf0 | ((cpt >> 18) & 0x07));
594
- result.push_back(0x80 | ((cpt >> 12) & 0x3f));
595
- result.push_back(0x80 | ((cpt >> 6) & 0x3f));
596
- result.push_back(0x80 | (cpt & 0x3f));
597
- return result;
598
- }
599
-
600
- throw std::invalid_argument("invalid codepoint");
601
- }
602
-
603
- std::vector<uint32_t> unicode_cpts_normalize_nfd(const std::vector<uint32_t> & cpts) {
604
- auto comp = [] (const uint32_t cpt, const range_nfd & range) {
605
- return cpt < range.first;
606
- };
607
- std::vector<uint32_t> result(cpts.size());
608
- for (size_t i = 0; i < cpts.size(); ++i) {
609
- const uint32_t cpt = cpts[i];
610
- auto it = std::upper_bound(unicode_ranges_nfd.begin(), unicode_ranges_nfd.end(), cpt, comp) - 1;
611
- result[i] = (it->first <= cpt && cpt <= it->last) ? it->nfd : cpt;
612
- }
613
- return result;
614
- }
615
-
616
- std::vector<uint32_t> unicode_cpts_from_utf8(const std::string & utf8) {
617
- std::vector<uint32_t> result;
618
- result.reserve(utf8.size());
619
- size_t offset = 0;
620
- while (offset < utf8.size()) {
621
- try {
622
- result.push_back(unicode_cpt_from_utf8(utf8, offset));
623
- }
624
- catch (const std::invalid_argument & /*ex*/) {
625
- // Silently ignore invalid UTF-8 input to avoid leaking the exception beyond llama_tokenize
626
- ++offset;
627
- result.emplace_back(0xFFFD); // replacement character
628
- }
629
- }
630
- return result;
631
- }
632
-
633
- unicode_cpt_flags unicode_cpt_flags_from_cpt(const uint32_t cpt) {
634
- static const unicode_cpt_flags undef(unicode_cpt_flags::UNDEFINED);
635
- static const auto cpt_flags = unicode_cpt_flags_array();
636
- return cpt < cpt_flags.size() ? cpt_flags[cpt] : undef;
637
- }
638
-
639
- unicode_cpt_flags unicode_cpt_flags_from_utf8(const std::string & utf8) {
640
- static const unicode_cpt_flags undef(unicode_cpt_flags::UNDEFINED);
641
- if (utf8.empty()) {
642
- return undef; // undefined
643
- }
644
- size_t offset = 0;
645
- return unicode_cpt_flags_from_cpt(unicode_cpt_from_utf8(utf8, offset));
646
- }
647
-
648
- std::string unicode_byte_to_utf8(uint8_t byte) {
649
- static std::unordered_map<uint8_t, std::string> map = unicode_byte_to_utf8_map();
650
- return map.at(byte);
651
- }
652
-
653
- uint8_t unicode_utf8_to_byte(const std::string & utf8) {
654
- static std::unordered_map<std::string, uint8_t> map = unicode_utf8_to_byte_map();
655
- return map.at(utf8);
656
- }
657
-
658
- uint32_t unicode_tolower(uint32_t cpt) {
659
- // binary search
660
- auto it = std::lower_bound(unicode_map_lowercase.begin(), unicode_map_lowercase.end(), cpt,
661
- [](const std::pair<uint32_t, uint32_t> & pair, uint32_t value) {
662
- return pair.first < value;
663
- });
664
- if (it != unicode_map_lowercase.end() && it->first == cpt) {
665
- return it->second;
666
- }
667
- return cpt; // Return the original code point if no lowercase mapping is found
668
- }
669
-
670
- std::vector<std::string> unicode_regex_split(const std::string & text, const std::vector<std::string> & regex_exprs) {
671
- // unicode categories
672
- static const std::map<std::string, int> k_ucat_enum = {
673
- { "\\p{N}", unicode_cpt_flags::NUMBER },
674
- { "\\p{L}", unicode_cpt_flags::LETTER },
675
- { "\\p{P}", unicode_cpt_flags::PUNCTUATION },
676
- { "\\p{M}", unicode_cpt_flags::ACCENT_MARK },
677
- { "\\p{S}", unicode_cpt_flags::SYMBOL },
678
- };
679
-
680
- static const std::map<int, int> k_ucat_cpt = {
681
- { unicode_cpt_flags::NUMBER, 0xD1 },
682
- { unicode_cpt_flags::LETTER, 0xD2 },
683
- { unicode_cpt_flags::PUNCTUATION, 0xD3 },
684
- { unicode_cpt_flags::ACCENT_MARK, 0xD4 },
685
- { unicode_cpt_flags::SYMBOL, 0xD5 },
686
- };
687
-
688
- static const std::map<int, std::string> k_ucat_map = {
689
- { unicode_cpt_flags::NUMBER, "\x30-\x39" }, // 0-9
690
- { unicode_cpt_flags::LETTER, "\x41-\x5A\x61-\x7A" }, // A-Za-z
691
- { unicode_cpt_flags::PUNCTUATION, "\x21-\x23\x25-\x2A\x2C-\x2F\x3A-\x3B\x3F-\x40\\\x5B-\\\x5D\x5F\\\x7B\\\x7D" }, // !-#%-*,-/:-;?-@\[-\]_\{\}
692
- { unicode_cpt_flags::ACCENT_MARK, "" }, // no sub-128 codepoints
693
- { unicode_cpt_flags::SYMBOL, "\\\x24\\\x2B\x3C-\x3E\x5E\x60\\\x7C" }, // $+<=>^`|
694
- };
695
-
696
- // compute collapsed codepoints only if needed by at least one regex
697
- bool need_collapse = false;
698
- for (const auto & regex_expr : regex_exprs) {
699
- // search for unicode categories
700
- for (const auto & ucat : k_ucat_enum) {
701
- if (std::string::npos != regex_expr.find(ucat.first)) {
702
- need_collapse = true;
703
- break;
704
- }
705
- }
706
- }
707
-
708
- const auto cpts = unicode_cpts_from_utf8(text);
709
-
710
- // generate a "collapsed" representation of the text, where all codepoints are replaced by a single byte
711
- // ref: https://github.com/ggml-org/llama.cpp/pull/6920#issuecomment-2081479935
712
- std::string text_collapsed;
713
- if (need_collapse) {
714
- // collapse all unicode categories
715
- text_collapsed.resize(cpts.size());
716
-
717
- for (size_t i = 0; i < cpts.size(); ++i) {
718
- // keep single-byte codepoints as is
719
- if (cpts[i] < 128) {
720
- text_collapsed[i] = cpts[i];
721
- continue;
722
- }
723
-
724
- const auto flags = unicode_cpt_flags_from_cpt(cpts[i]);
725
-
726
- if (flags.is_whitespace) {
727
- //NOTE: C++ std::regex \s does not mach 0x85, Rust and Python regex does.
728
- //text_collapsed[i] = (char) 0x85; // <Next Line> as whitespace fallback
729
- text_collapsed[i] = (char) 0x0B; // <vertical tab> as whitespace fallback
730
- } else if (k_ucat_cpt.find(flags.category_flag()) != k_ucat_cpt.end()) {
731
- text_collapsed[i] = k_ucat_cpt.at(flags.category_flag());
732
- } else {
733
- text_collapsed[i] = (char) 0xD0; // fallback
734
- }
735
- }
736
- }
737
-
738
- std::vector<size_t> bpe_offsets = { cpts.size() };
739
-
740
- for (const auto & regex_expr : regex_exprs) {
741
- // first, see if we have an efficient custom regex implementation
742
- auto tmp = unicode_regex_split_custom(text, regex_expr, bpe_offsets);
743
-
744
- if (!tmp.empty()) {
745
- bpe_offsets = std::move(tmp);
746
- continue;
747
- }
748
-
749
- // fallback to general-purpose std::regex / std::wregex
750
- try {
751
- // if a unicode category is used in the regex, we use the collapsed text and replace the unicode category
752
- // with the corresponding collapsed representation
753
- bool use_collapsed = false;
754
- for (const auto & ucat : k_ucat_enum) {
755
- if (std::string::npos != regex_expr.find(ucat.first)) {
756
- use_collapsed = true;
757
- break;
758
- }
759
- }
760
-
761
- if (use_collapsed) {
762
- // sanity-check that the original regex does not contain any non-ASCII characters
763
- const auto cpts_regex = unicode_cpts_from_utf8(regex_expr);
764
- for (size_t i = 0; i < cpts_regex.size(); ++i) {
765
- if (cpts_regex[i] >= 128) {
766
- throw std::runtime_error("Regex includes both unicode categories and non-ASCII characters - not supported");
767
- }
768
- }
769
-
770
- // generate a collapsed representation of the regex
771
- std::string regex_expr_collapsed;
772
-
773
- // track if we are inside [], because nested [] are not allowed
774
- bool inside = false;
775
- for (size_t i = 0; i < regex_expr.size(); ++i) {
776
- if (regex_expr[i] == '[' && (i == 0 || regex_expr[i - 1] != '\\')) {
777
- regex_expr_collapsed += '[';
778
- inside = true;
779
- continue;
780
- }
781
-
782
- if (inside && regex_expr[i] == ']' && regex_expr[i - 1] != '\\') {
783
- regex_expr_collapsed += ']';
784
- inside = false;
785
- continue;
786
- }
787
-
788
- if (regex_expr[i + 0] == '\\' && i + 4 < regex_expr.size() &&
789
- regex_expr[i + 1] == 'p' &&
790
- regex_expr[i + 2] == '{' &&
791
- regex_expr[i + 4] == '}') {
792
- const std::string pat = regex_expr.substr(i, 5);
793
- if (k_ucat_enum.find(pat) != k_ucat_enum.end()) {
794
- if (!inside) {
795
- regex_expr_collapsed += '[';
796
- }
797
- regex_expr_collapsed += k_ucat_cpt.at(k_ucat_enum.at(pat));
798
- regex_expr_collapsed += k_ucat_map.at(k_ucat_enum.at(pat));
799
- if (!inside) {
800
- regex_expr_collapsed += ']';
801
- }
802
- i += 4;
803
- continue;
804
- }
805
- }
806
-
807
- regex_expr_collapsed += regex_expr[i];
808
- }
809
-
810
- //printf("text_collapsed: %s\n", text_collapsed.c_str());
811
- //printf("regex_expr_collapsed: %s\n", regex_expr_collapsed.c_str());
812
- bpe_offsets = unicode_regex_split_stl(text_collapsed, regex_expr_collapsed, bpe_offsets);
813
- } else {
814
- // no unicode category used, we can use std::wregex directly
815
- const std::wstring wregex_expr = unicode_wstring_from_utf8(regex_expr);
816
-
817
- // std::wregex \s does not mach non-ASCII whitespaces, using 0x0B as fallback
818
- std::wstring wtext(cpts.begin(), cpts.end());
819
- for (size_t i = 0; i < wtext.size(); ++i) {
820
- if (wtext[i] > 0x7F && unicode_cpt_flags_from_cpt(wtext[i]).is_whitespace) {
821
- wtext[i] = 0x0B;
822
- }
823
- }
824
-
825
- //printf("text: %s\n", text.c_str());
826
- //printf("regex_expr: %s\n", regex_expr.c_str());
827
- bpe_offsets = unicode_regex_split_stl(wtext, wregex_expr, bpe_offsets);
828
- }
829
- } catch (std::regex_error & e) {
830
- fprintf(stderr, "Failed to process regex: '%s'\n", regex_expr.c_str());
831
- fprintf(stderr, "Regex error: %s\n", e.what());
832
- throw std::runtime_error("Failed to process regex");
833
- }
834
- }
835
-
836
- std::vector<std::string> bpe_words;
837
- bpe_words.reserve(bpe_offsets.size()); // reserve memory for the approximate size
838
-
839
- size_t start = 0;
840
- for (size_t & offset : bpe_offsets) {
841
- bpe_words.emplace_back();
842
- for (size_t i = start; i < start + offset; ++i) {
843
- bpe_words.back() += unicode_cpt_to_utf8(cpts[i]);
844
- }
845
- start += offset;
846
- }
847
-
848
- return unicode_byte_encoding_process(bpe_words);
849
- }
1
+ #if defined(_MSC_VER)
2
+ #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
3
+ #endif
4
+
5
+ #include "unicode.h"
6
+ #include "unicode-data.h"
7
+
8
+ #include <algorithm>
9
+ #include <cassert>
10
+ #include <codecvt>
11
+ #include <cstddef>
12
+ #include <cstdint>
13
+ #include <locale>
14
+ #include <map>
15
+ #include <regex>
16
+ #include <stdexcept>
17
+ #include <string>
18
+ #include <unordered_map>
19
+ #include <utility>
20
+ #include <vector>
21
+
22
+ size_t unicode_len_utf8(char src) {
23
+ const size_t lookup[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4 };
24
+ uint8_t highbits = static_cast<uint8_t>(src) >> 4;
25
+ return lookup[highbits];
26
+ }
27
+
28
+ static std::string unicode_cpts_to_utf8(const std::vector<uint32_t> & cps) {
29
+ std::string result;
30
+ for (size_t i = 0; i < cps.size(); ++i) {
31
+ result.append(unicode_cpt_to_utf8(cps[i]));
32
+ }
33
+ return result;
34
+ }
35
+
36
+ uint32_t unicode_cpt_from_utf8(const std::string & utf8, size_t & offset) {
37
+ assert(offset < utf8.size());
38
+ if (!(utf8[offset + 0] & 0x80)) {
39
+ auto result = utf8[offset + 0];
40
+ offset += 1;
41
+ return result;
42
+ }
43
+ if (!(utf8[offset + 0] & 0x40)) {
44
+ throw std::invalid_argument("invalid character");
45
+ }
46
+ if (!(utf8[offset + 0] & 0x20)) {
47
+ if (offset + 1 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80)) {
48
+ throw std::invalid_argument("invalid character");
49
+ }
50
+ auto result = ((utf8[offset + 0] & 0x1f) << 6) | (utf8[offset + 1] & 0x3f);
51
+ offset += 2;
52
+ return result;
53
+ }
54
+ if (!(utf8[offset + 0] & 0x10)) {
55
+ if (offset + 2 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80) || ! ((utf8[offset + 2] & 0xc0) == 0x80)) {
56
+ throw std::invalid_argument("invalid character");
57
+ }
58
+ auto result = ((utf8[offset + 0] & 0x0f) << 12) | ((utf8[offset + 1] & 0x3f) << 6) | (utf8[offset + 2] & 0x3f);
59
+ offset += 3;
60
+ return result;
61
+ }
62
+ if (!(utf8[offset + 0] & 0x08)) {
63
+ if (offset + 3 >= utf8.size() || ! ((utf8[offset + 1] & 0xc0) == 0x80) || ! ((utf8[offset + 2] & 0xc0) == 0x80) || !((utf8[offset + 3] & 0xc0) == 0x80)) {
64
+ throw std::invalid_argument("invalid character");
65
+ }
66
+ auto result = ((utf8[offset + 0] & 0x07) << 18) | ((utf8[offset + 1] & 0x3f) << 12) | ((utf8[offset + 2] & 0x3f) << 6) | (utf8[offset + 3] & 0x3f);
67
+ offset += 4;
68
+ return result;
69
+ }
70
+ throw std::invalid_argument("failed to convert utf8 to codepoint");
71
+ }
72
+
73
+ //static std::vector<uint16_t> unicode_cpt_to_utf16(uint32_t cpt) {
74
+ // std::vector<uint16_t> result;
75
+ // if (/* 0x0000 <= cpt && */ cpt <= 0xffff) {
76
+ // result.emplace_back(cpt);
77
+ // return result;
78
+ // }
79
+ // if (0x10000 <= cpt && cpt <= 0x10ffff) {
80
+ // result.emplace_back(0xd800 | ((cpt - 0x10000) >> 10));
81
+ // result.emplace_back(0xdc00 | ((cpt - 0x10000) & 0x03ff));
82
+ // return result;
83
+ // }
84
+ // throw std::invalid_argument("failed to convert codepoint to utf16");
85
+ //}
86
+
87
+ //static std::vector<uint16_t> unicode_cpts_to_utf16(const std::vector<uint32_t> & cps) {
88
+ // std::vector<uint16_t> result;
89
+ // for (size_t i = 0; i < cps.size(); ++i) {
90
+ // auto temp = unicode_cpt_to_utf16(cps[i]);
91
+ // result.insert(result.end(), temp.begin(), temp.end());
92
+ // }
93
+ // return result;
94
+ //}
95
+
96
+ //static uint32_t unicode_cpt_from_utf16(const std::vector<uint16_t> & utf16, size_t & offset) {
97
+ // assert(offset < utf16.size());
98
+ // if (((utf16[0] >> 10) << 10) != 0xd800) {
99
+ // auto result = utf16[offset + 0];
100
+ // offset += 1;
101
+ // return result;
102
+ // }
103
+ //
104
+ // if (offset + 1 >= utf16.size() || !((utf16[1] & 0xdc00) == 0xdc00)) {
105
+ // throw std::invalid_argument("invalid character");
106
+ // }
107
+ //
108
+ // auto result = 0x10000 + (((utf16[0] & 0x03ff) << 10) | (utf16[1] & 0x03ff));
109
+ // offset += 2;
110
+ // return result;
111
+ //}
112
+
113
+ //static std::vector<uint32_t> unicode_cpts_from_utf16(const std::vector<uint16_t> & utf16) {
114
+ // std::vector<uint32_t> result;
115
+ // size_t offset = 0;
116
+ // while (offset < utf16.size()) {
117
+ // result.push_back(unicode_cpt_from_utf16(utf16, offset));
118
+ // }
119
+ // return result;
120
+ //}
121
+
122
+ static std::vector<unicode_cpt_flags> unicode_cpt_flags_array() {
123
+ std::vector<unicode_cpt_flags> cpt_flags(MAX_CODEPOINTS, unicode_cpt_flags::UNDEFINED);
124
+
125
+ assert (unicode_ranges_flags.begin()[0].first == 0);
126
+ assert (unicode_ranges_flags.begin()[unicode_ranges_flags.size()-1].first == MAX_CODEPOINTS);
127
+ for (size_t i = 1; i < unicode_ranges_flags.size(); ++i) {
128
+ const auto range_ini = unicode_ranges_flags.begin()[i-1]; // codepoint_ini, flags
129
+ const auto range_end = unicode_ranges_flags.begin()[i]; // codepoint_end, flags
130
+ for (uint32_t cpt = range_ini.first; cpt < range_end.first; ++cpt) {
131
+ cpt_flags[cpt] = range_ini.second;
132
+ }
133
+ }
134
+
135
+ for (auto cpt : unicode_set_whitespace) {
136
+ cpt_flags[cpt].is_whitespace = true;
137
+ }
138
+
139
+ for (auto p : unicode_map_lowercase) {
140
+ cpt_flags[p.second].is_lowercase = true;
141
+ }
142
+
143
+ for (auto p : unicode_map_uppercase) {
144
+ cpt_flags[p.second].is_uppercase = true;
145
+ }
146
+
147
+ for (auto &range : unicode_ranges_nfd) { // start, last, nfd
148
+ cpt_flags[range.nfd].is_nfd = true;
149
+ }
150
+
151
+ return cpt_flags;
152
+ }
153
+
154
+ static std::unordered_map<uint8_t, std::string> unicode_byte_to_utf8_map() {
155
+ std::unordered_map<uint8_t, std::string> map;
156
+ for (int ch = 0x21; ch <= 0x7E; ++ch) { // u'!' to u'~'
157
+ assert(0 <= ch && ch < 256);
158
+ map[ch] = unicode_cpt_to_utf8(ch);
159
+ }
160
+ for (int ch = 0xA1; ch <= 0xAC; ++ch) { // u'¡' to u'¬'
161
+ assert(0 <= ch && ch < 256);
162
+ map[ch] = unicode_cpt_to_utf8(ch);
163
+ }
164
+ for (int ch = 0xAE; ch <= 0xFF; ++ch) { // u'®' to u'ÿ'
165
+ assert(0 <= ch && ch < 256);
166
+ map[ch] = unicode_cpt_to_utf8(ch);
167
+ }
168
+ auto n = 0;
169
+ for (int ch = 0; ch < 256; ++ch) {
170
+ if (map.find(ch) == map.end()) {
171
+ map[ch] = unicode_cpt_to_utf8(256 + n);
172
+ ++n;
173
+ }
174
+ }
175
+ return map;
176
+ }
177
+
178
+ static std::unordered_map<std::string, uint8_t> unicode_utf8_to_byte_map() {
179
+ std::unordered_map<std::string, uint8_t> map;
180
+ for (int ch = 0x21; ch <= 0x7E; ++ch) { // u'!' to u'~'
181
+ assert(0 <= ch && ch < 256);
182
+ map[unicode_cpt_to_utf8(ch)] = ch;
183
+ }
184
+ for (int ch = 0xA1; ch <= 0xAC; ++ch) { // u'¡' to u'¬'
185
+ assert(0 <= ch && ch < 256);
186
+ map[unicode_cpt_to_utf8(ch)] = ch;
187
+ }
188
+ for (int ch = 0xAE; ch <= 0xFF; ++ch) { // u'®' to u'ÿ'
189
+ assert(0 <= ch && ch < 256);
190
+ map[unicode_cpt_to_utf8(ch)] = ch;
191
+ }
192
+ auto n = 0;
193
+ for (int ch = 0; ch < 256; ++ch) {
194
+ if (map.find(unicode_cpt_to_utf8(ch)) == map.end()) {
195
+ map[unicode_cpt_to_utf8(256 + n)] = ch;
196
+ ++n;
197
+ }
198
+ }
199
+ return map;
200
+ }
201
+
202
+ static inline std::wstring unicode_wstring_from_utf8(const std::string & s) {
203
+ #if defined(__clang__)
204
+ // disable C++17 deprecation warning for std::codecvt_utf8
205
+ # pragma clang diagnostic push
206
+ # pragma clang diagnostic ignored "-Wdeprecated-declarations"
207
+ #endif
208
+
209
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
210
+
211
+ #if defined(__clang__)
212
+ # pragma clang diagnostic pop
213
+ #endif
214
+
215
+ return conv.from_bytes(s);
216
+ }
217
+
218
+ static std::vector<std::string> unicode_byte_encoding_process(const std::vector<std::string> & bpe_words) {
219
+ std::vector<std::string> bpe_encoded_words;
220
+ for (const auto & word : bpe_words) {
221
+ std::string text_utf;
222
+ auto utf_word = unicode_cpts_from_utf8(word);
223
+ for (size_t i = 0; i < utf_word.size(); ++i) {
224
+ text_utf += unicode_cpt_to_utf8(utf_word[i]);
225
+ }
226
+
227
+ std::string encoded_token;
228
+ for (char & c : text_utf) {
229
+ encoded_token += unicode_byte_to_utf8(c);
230
+ }
231
+ bpe_encoded_words.emplace_back(encoded_token);
232
+ }
233
+ return bpe_encoded_words;
234
+ }
235
+
236
+ // GPT2 system regex: 's|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+
237
+ static std::vector<size_t> unicode_regex_split_custom_gpt2(const std::string & text, const std::vector<size_t> & offsets) {
238
+ std::vector<size_t> bpe_offsets; // store the offset of each word
239
+ bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
240
+
241
+ const auto cpts = unicode_cpts_from_utf8(text);
242
+
243
+ size_t start = 0;
244
+ for (auto offset : offsets) {
245
+ const size_t offset_ini = start;
246
+ const size_t offset_end = start + offset;
247
+ assert(offset_end <= cpts.size());
248
+ start = offset_end;
249
+
250
+ static const uint32_t OUT_OF_RANGE = 0xFFFFFFFF;
251
+ auto _get_cpt = [&] (const size_t pos) -> uint32_t {
252
+ return (offset_ini <= pos && pos < offset_end) ? cpts[pos] : OUT_OF_RANGE;
253
+ };
254
+
255
+ auto _get_flags = [&] (const size_t pos) -> unicode_cpt_flags {
256
+ return (offset_ini <= pos && pos < offset_end) ? unicode_cpt_flags_from_cpt(cpts[pos]) : unicode_cpt_flags{};
257
+ };
258
+
259
+ size_t _prev_end = offset_ini;
260
+ auto _add_token = [&] (const size_t end) -> size_t {
261
+ assert(_prev_end <= end && end <= offset_end);
262
+ size_t len = end - _prev_end;
263
+ if (len > 0) {
264
+ bpe_offsets.push_back(len);
265
+ }
266
+ _prev_end = end;
267
+ //if (len > 0) {
268
+ // std::string s = "";
269
+ // for(size_t p = end-len; p < end; p++)
270
+ // s += unicode_cpt_to_utf8(cpts[p]);
271
+ // printf(">>> '%s'\n", s.c_str());
272
+ //}
273
+ return len;
274
+ };
275
+
276
+ for (size_t pos = offset_ini; pos < offset_end; /*pos++*/ ) {
277
+ const uint32_t cpt = _get_cpt(pos);
278
+ const auto flags = _get_flags(pos);
279
+
280
+ // regex: 's|'t|'re|'ve|'m|'ll|'d
281
+ if (cpt == '\'' && pos+1 < offset_end) {
282
+ uint32_t cpt_next = _get_cpt(pos+1);
283
+ if (cpt_next == 's' || cpt_next == 't' || cpt_next == 'm' || cpt_next == 'd') {
284
+ pos += _add_token(pos+2);
285
+ continue;
286
+ }
287
+ if (pos+2 < offset_end) {
288
+ uint32_t cpt_next_next = _get_cpt(pos+2);
289
+ if ((cpt_next == 'r' && cpt_next_next == 'e') ||
290
+ (cpt_next == 'v' && cpt_next_next == 'e') ||
291
+ (cpt_next == 'l' && cpt_next_next == 'l')) {
292
+ pos += _add_token(pos+3);
293
+ continue;
294
+ }
295
+ }
296
+ }
297
+
298
+ auto flags2 = (cpt == ' ' ? _get_flags(pos+1) : flags);
299
+ // regex: <space>?\p{L}+
300
+ if (flags2.is_letter) {
301
+ pos += (cpt == ' ');
302
+ while (flags2.is_letter) {
303
+ flags2 = _get_flags(++pos);
304
+ }
305
+ _add_token(pos);
306
+ continue;
307
+ }
308
+ // regex: <space>?\p{N}+
309
+ if (flags2.is_number) {
310
+ pos += (cpt == ' ');
311
+ while (flags2.is_number) {
312
+ flags2 = _get_flags(++pos);
313
+ }
314
+ _add_token(pos);
315
+ continue;
316
+ }
317
+ // regex: <space>?[^\s\p{L}\p{N}]+
318
+ if (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
319
+ pos += (cpt == ' ');
320
+ while (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
321
+ flags2 = _get_flags(++pos);
322
+ }
323
+ _add_token(pos);
324
+ continue;
325
+ }
326
+
327
+ size_t num_whitespaces = 0;
328
+ while (_get_flags(pos+num_whitespaces).is_whitespace) {
329
+ num_whitespaces++;
330
+ }
331
+
332
+ // regex: \s+(?!\S)
333
+ if (num_whitespaces > 1 && _get_cpt(pos+num_whitespaces) != OUT_OF_RANGE) {
334
+ pos += num_whitespaces - 1;
335
+ _add_token(pos);
336
+ continue;
337
+ }
338
+
339
+ // regex: \s+
340
+ if (num_whitespaces > 0) {
341
+ pos += num_whitespaces;
342
+ _add_token(pos);
343
+ continue;
344
+ }
345
+
346
+ // no matches
347
+ _add_token(++pos);
348
+ }
349
+ }
350
+
351
+ return bpe_offsets;
352
+ }
353
+
354
+ // LLAMA3 system regex: "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+"
355
+ static std::vector<size_t> unicode_regex_split_custom_llama3(const std::string & text, const std::vector<size_t> & offsets) {
356
+ std::vector<size_t> bpe_offsets; // store the offset of each word
357
+ bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
358
+
359
+ const auto cpts = unicode_cpts_from_utf8(text);
360
+
361
+ size_t start = 0;
362
+ for (auto offset : offsets) {
363
+ const size_t offset_ini = start;
364
+ const size_t offset_end = start + offset;
365
+ assert(offset_end <= cpts.size());
366
+ start = offset_end;
367
+
368
+ static const uint32_t OUT_OF_RANGE = 0xFFFFFFFF;
369
+ auto _get_cpt = [&] (const size_t pos) -> uint32_t {
370
+ return (offset_ini <= pos && pos < offset_end) ? cpts[pos] : OUT_OF_RANGE;
371
+ };
372
+
373
+ auto _get_flags = [&] (const size_t pos) -> unicode_cpt_flags {
374
+ return (offset_ini <= pos && pos < offset_end) ? unicode_cpt_flags_from_cpt(cpts[pos]) : unicode_cpt_flags{};
375
+ };
376
+
377
+ size_t _prev_end = offset_ini;
378
+ auto _add_token = [&] (const size_t end) -> size_t {
379
+ assert(_prev_end <= end && end <= offset_end);
380
+ size_t len = end - _prev_end;
381
+ if (len > 0) {
382
+ bpe_offsets.push_back(len);
383
+ }
384
+ _prev_end = end;
385
+ //if (len > 0) {
386
+ // std::string s = "";
387
+ // for(size_t p = end-len; p < end; p++)
388
+ // s += unicode_cpt_to_utf8(cpts[p]);
389
+ // printf(">>> '%s'\n", s.c_str());
390
+ //}
391
+ return len;
392
+ };
393
+
394
+ for (size_t pos = offset_ini; pos < offset_end; /*pos++*/ ) {
395
+ const uint32_t cpt = _get_cpt(pos);
396
+ const auto flags = _get_flags(pos);
397
+
398
+ // regex: (?i:'s|'t|'re|'ve|'m|'ll|'d) // case insensitive
399
+ if (cpt == '\'' && pos+1 < offset_end) {
400
+ uint32_t cpt_next = unicode_tolower(_get_cpt(pos+1));
401
+ if (cpt_next == 's' || cpt_next == 't' || cpt_next == 'm' || cpt_next == 'd') {
402
+ pos += _add_token(pos+2);
403
+ continue;
404
+ }
405
+ if (pos+2 < offset_end) {
406
+ uint32_t cpt_next_next = unicode_tolower(_get_cpt(pos+2));
407
+ if ((cpt_next == 'r' && cpt_next_next == 'e') ||
408
+ (cpt_next == 'v' && cpt_next_next == 'e') ||
409
+ (cpt_next == 'l' && cpt_next_next == 'l')) {
410
+ pos += _add_token(pos+3);
411
+ continue;
412
+ }
413
+ }
414
+ }
415
+
416
+ // regex: [^\r\n\p{L}\p{N}]?\p{L}+
417
+ if (!(cpt == '\r' || cpt == '\n' || flags.is_number)) {
418
+ if (flags.is_letter || _get_flags(pos+1).is_letter) { // one or more letters
419
+ pos++;
420
+ while (_get_flags(pos).is_letter) {
421
+ pos++;
422
+ }
423
+ _add_token(pos);
424
+ continue;
425
+ }
426
+ }
427
+
428
+ // regex: \p{N}{1,3}
429
+ if (flags.is_number) {
430
+ size_t ini = pos;
431
+ while (_get_flags(pos).is_number) {
432
+ if (++pos - ini >= 3 ) {
433
+ _add_token(pos);
434
+ ini = pos;
435
+ }
436
+ }
437
+ _add_token(pos);
438
+ continue;
439
+ }
440
+
441
+ // regex: <space>?[^\s\p{L}\p{N}]+[\r\n]*
442
+ auto flags2 = (cpt == ' ' ? _get_flags(pos+1) : flags);
443
+ if (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags.as_uint()) {
444
+ pos += (cpt == ' ');
445
+ while (!(flags2.is_whitespace | flags2.is_letter | flags2.is_number) && flags2.as_uint()) {
446
+ flags2 = _get_flags(++pos);
447
+ }
448
+ uint32_t cpt2 = _get_cpt(pos);
449
+ while (cpt2 == '\r' || cpt2 == '\n') {
450
+ cpt2 = _get_cpt(++pos);
451
+ }
452
+ _add_token(pos);
453
+ continue;
454
+ }
455
+
456
+ size_t num_whitespaces = 0;
457
+ size_t last_end_r_or_n = 0;
458
+ while (_get_flags(pos+num_whitespaces).is_whitespace) {
459
+ uint32_t cpt2 = _get_cpt(pos+num_whitespaces);
460
+ if (cpt2 == '\r' || cpt2 == '\n') {
461
+ last_end_r_or_n = pos + num_whitespaces + 1;
462
+ }
463
+ num_whitespaces++;
464
+ }
465
+
466
+ // regex: \s*[\r\n]+
467
+ if (last_end_r_or_n > 0) {
468
+ pos = last_end_r_or_n;
469
+ _add_token(pos);
470
+ continue;
471
+ }
472
+
473
+ // regex: \s+(?!\S)
474
+ if (num_whitespaces > 1 && _get_cpt(pos+num_whitespaces) != OUT_OF_RANGE) {
475
+ pos += num_whitespaces - 1;
476
+ _add_token(pos);
477
+ continue;
478
+ }
479
+
480
+ // regex: \s+
481
+ if (num_whitespaces > 0) {
482
+ pos += num_whitespaces;
483
+ _add_token(pos);
484
+ continue;
485
+ }
486
+
487
+ // no matches
488
+ _add_token(++pos);
489
+ }
490
+ }
491
+
492
+ return bpe_offsets;
493
+ }
494
+
495
+ // use std::wregex to split the text
496
+ static std::vector<size_t> unicode_regex_split_stl(const std::wstring & wtext, const std::wstring & regex_expr, const std::vector<size_t> & offsets) {
497
+ std::wregex expr(regex_expr);
498
+ std::vector<size_t> bpe_offsets; // store the offset of each word
499
+ bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
500
+ size_t start = 0;
501
+ for (auto offset : offsets) {
502
+ std::wcregex_iterator it(wtext.data() + start, wtext.data() + start + offset, expr);
503
+ std::wcregex_iterator end;
504
+
505
+ int64_t start_idx = 0;
506
+ while (it != end) {
507
+ std::wcmatch match = *it;
508
+ if (match.position() > start_idx) {
509
+ bpe_offsets.emplace_back(match.position() - start_idx);
510
+ }
511
+ bpe_offsets.emplace_back(match.length());
512
+ start_idx = match.position() + match.length();
513
+ ++it;
514
+ }
515
+
516
+ if (start_idx < (int64_t) offset) {
517
+ bpe_offsets.emplace_back(offset - start_idx);
518
+ }
519
+ start += offset;
520
+ }
521
+
522
+ return bpe_offsets;
523
+ }
524
+
525
+ // use std::regex to split the text
526
+ static std::vector<size_t> unicode_regex_split_stl(const std::string & text, const std::string & regex_expr, const std::vector<size_t> & offsets) {
527
+ std::regex expr(regex_expr);
528
+ std::vector<size_t> bpe_offsets; // store the offset of each word
529
+ bpe_offsets.reserve(offsets.size()); // Reserve memory for the approximate size
530
+ size_t start = 0;
531
+ for (auto offset : offsets) {
532
+ std::cregex_iterator it(text.data() + start, text.data() + start + offset, expr);
533
+ std::cregex_iterator end;
534
+
535
+ int64_t start_idx = 0;
536
+ while (it != end) {
537
+ std::cmatch match = *it;
538
+ if (match.position() > start_idx) {
539
+ bpe_offsets.emplace_back(match.position() - start_idx);
540
+ }
541
+ bpe_offsets.emplace_back(match.length());
542
+ start_idx = match.position() + match.length();
543
+ ++it;
544
+ }
545
+
546
+ if (start_idx < (int64_t) offset) {
547
+ bpe_offsets.emplace_back(offset - start_idx);
548
+ }
549
+ start += offset;
550
+ }
551
+
552
+ return bpe_offsets;
553
+ }
554
+
555
+ static std::vector<size_t> unicode_regex_split_custom(const std::string & text, const std::string & regex_expr, const std::vector<size_t> & offsets) {
556
+ std::vector<size_t> bpe_offsets;
557
+
558
+ if (regex_expr == "'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)") {
559
+ bpe_offsets = unicode_regex_split_custom_gpt2(text, offsets);
560
+ } else if (
561
+ regex_expr == "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?\\p{L}+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+" ||
562
+ regex_expr == "(?:'[sS]|'[tT]|'[rR][eE]|'[vV][eE]|'[mM]|'[lL][lL]|'[dD])|[^\\r\\n\\p{L}\\p{N}]?\\p{L}+|\\p{N}{1,3}| ?[^\\s\\p{L}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+") {
563
+
564
+ bpe_offsets = unicode_regex_split_custom_llama3(text, offsets);
565
+ }
566
+
567
+ return bpe_offsets;
568
+ }
569
+
570
+ //
571
+ // interface
572
+ //
573
+
574
+ std::string unicode_cpt_to_utf8(uint32_t cpt) {
575
+ std::string result;
576
+
577
+ if (/* 0x00 <= cpt && */ cpt <= 0x7f) {
578
+ result.push_back(cpt);
579
+ return result;
580
+ }
581
+ if (0x80 <= cpt && cpt <= 0x7ff) {
582
+ result.push_back(0xc0 | ((cpt >> 6) & 0x1f));
583
+ result.push_back(0x80 | (cpt & 0x3f));
584
+ return result;
585
+ }
586
+ if (0x800 <= cpt && cpt <= 0xffff) {
587
+ result.push_back(0xe0 | ((cpt >> 12) & 0x0f));
588
+ result.push_back(0x80 | ((cpt >> 6) & 0x3f));
589
+ result.push_back(0x80 | (cpt & 0x3f));
590
+ return result;
591
+ }
592
+ if (0x10000 <= cpt && cpt <= 0x10ffff) {
593
+ result.push_back(0xf0 | ((cpt >> 18) & 0x07));
594
+ result.push_back(0x80 | ((cpt >> 12) & 0x3f));
595
+ result.push_back(0x80 | ((cpt >> 6) & 0x3f));
596
+ result.push_back(0x80 | (cpt & 0x3f));
597
+ return result;
598
+ }
599
+
600
+ throw std::invalid_argument("invalid codepoint");
601
+ }
602
+
603
+ std::vector<uint32_t> unicode_cpts_normalize_nfd(const std::vector<uint32_t> & cpts) {
604
+ auto comp = [] (const uint32_t cpt, const range_nfd & range) {
605
+ return cpt < range.first;
606
+ };
607
+ std::vector<uint32_t> result(cpts.size());
608
+ for (size_t i = 0; i < cpts.size(); ++i) {
609
+ const uint32_t cpt = cpts[i];
610
+ auto it = std::upper_bound(unicode_ranges_nfd.begin(), unicode_ranges_nfd.end(), cpt, comp) - 1;
611
+ result[i] = (it->first <= cpt && cpt <= it->last) ? it->nfd : cpt;
612
+ }
613
+ return result;
614
+ }
615
+
616
+ std::vector<uint32_t> unicode_cpts_from_utf8(const std::string & utf8) {
617
+ std::vector<uint32_t> result;
618
+ result.reserve(utf8.size());
619
+ size_t offset = 0;
620
+ while (offset < utf8.size()) {
621
+ try {
622
+ result.push_back(unicode_cpt_from_utf8(utf8, offset));
623
+ }
624
+ catch (const std::invalid_argument & /*ex*/) {
625
+ // Silently ignore invalid UTF-8 input to avoid leaking the exception beyond llama_tokenize
626
+ ++offset;
627
+ result.emplace_back(0xFFFD); // replacement character
628
+ }
629
+ }
630
+ return result;
631
+ }
632
+
633
+ unicode_cpt_flags unicode_cpt_flags_from_cpt(const uint32_t cpt) {
634
+ static const unicode_cpt_flags undef(unicode_cpt_flags::UNDEFINED);
635
+ static const auto cpt_flags = unicode_cpt_flags_array();
636
+ return cpt < cpt_flags.size() ? cpt_flags[cpt] : undef;
637
+ }
638
+
639
+ unicode_cpt_flags unicode_cpt_flags_from_utf8(const std::string & utf8) {
640
+ static const unicode_cpt_flags undef(unicode_cpt_flags::UNDEFINED);
641
+ if (utf8.empty()) {
642
+ return undef; // undefined
643
+ }
644
+ size_t offset = 0;
645
+ return unicode_cpt_flags_from_cpt(unicode_cpt_from_utf8(utf8, offset));
646
+ }
647
+
648
+ std::string unicode_byte_to_utf8(uint8_t byte) {
649
+ static std::unordered_map<uint8_t, std::string> map = unicode_byte_to_utf8_map();
650
+ return map.at(byte);
651
+ }
652
+
653
+ uint8_t unicode_utf8_to_byte(const std::string & utf8) {
654
+ static std::unordered_map<std::string, uint8_t> map = unicode_utf8_to_byte_map();
655
+ return map.at(utf8);
656
+ }
657
+
658
+ uint32_t unicode_tolower(uint32_t cpt) {
659
+ // binary search
660
+ auto it = std::lower_bound(unicode_map_lowercase.begin(), unicode_map_lowercase.end(), cpt,
661
+ [](const std::pair<uint32_t, uint32_t> & pair, uint32_t value) {
662
+ return pair.first < value;
663
+ });
664
+ if (it != unicode_map_lowercase.end() && it->first == cpt) {
665
+ return it->second;
666
+ }
667
+ return cpt; // Return the original code point if no lowercase mapping is found
668
+ }
669
+
670
+ std::vector<std::string> unicode_regex_split(const std::string & text, const std::vector<std::string> & regex_exprs) {
671
+ // unicode categories
672
+ static const std::map<std::string, int> k_ucat_enum = {
673
+ { "\\p{N}", unicode_cpt_flags::NUMBER },
674
+ { "\\p{L}", unicode_cpt_flags::LETTER },
675
+ { "\\p{P}", unicode_cpt_flags::PUNCTUATION },
676
+ { "\\p{M}", unicode_cpt_flags::ACCENT_MARK },
677
+ { "\\p{S}", unicode_cpt_flags::SYMBOL },
678
+ };
679
+
680
+ static const std::map<int, int> k_ucat_cpt = {
681
+ { unicode_cpt_flags::NUMBER, 0xD1 },
682
+ { unicode_cpt_flags::LETTER, 0xD2 },
683
+ { unicode_cpt_flags::PUNCTUATION, 0xD3 },
684
+ { unicode_cpt_flags::ACCENT_MARK, 0xD4 },
685
+ { unicode_cpt_flags::SYMBOL, 0xD5 },
686
+ };
687
+
688
+ static const std::map<int, std::string> k_ucat_map = {
689
+ { unicode_cpt_flags::NUMBER, "\x30-\x39" }, // 0-9
690
+ { unicode_cpt_flags::LETTER, "\x41-\x5A\x61-\x7A" }, // A-Za-z
691
+ { unicode_cpt_flags::PUNCTUATION, "\x21-\x23\x25-\x2A\x2C-\x2F\x3A-\x3B\x3F-\x40\\\x5B-\\\x5D\x5F\\\x7B\\\x7D" }, // !-#%-*,-/:-;?-@\[-\]_\{\}
692
+ { unicode_cpt_flags::ACCENT_MARK, "" }, // no sub-128 codepoints
693
+ { unicode_cpt_flags::SYMBOL, "\\\x24\\\x2B\x3C-\x3E\x5E\x60\\\x7C" }, // $+<=>^`|
694
+ };
695
+
696
+ // compute collapsed codepoints only if needed by at least one regex
697
+ bool need_collapse = false;
698
+ for (const auto & regex_expr : regex_exprs) {
699
+ // search for unicode categories
700
+ for (const auto & ucat : k_ucat_enum) {
701
+ if (std::string::npos != regex_expr.find(ucat.first)) {
702
+ need_collapse = true;
703
+ break;
704
+ }
705
+ }
706
+ }
707
+
708
+ const auto cpts = unicode_cpts_from_utf8(text);
709
+
710
+ // generate a "collapsed" representation of the text, where all codepoints are replaced by a single byte
711
+ // ref: https://github.com/ggml-org/llama.cpp/pull/6920#issuecomment-2081479935
712
+ std::string text_collapsed;
713
+ if (need_collapse) {
714
+ // collapse all unicode categories
715
+ text_collapsed.resize(cpts.size());
716
+
717
+ for (size_t i = 0; i < cpts.size(); ++i) {
718
+ // keep single-byte codepoints as is
719
+ if (cpts[i] < 128) {
720
+ text_collapsed[i] = cpts[i];
721
+ continue;
722
+ }
723
+
724
+ const auto flags = unicode_cpt_flags_from_cpt(cpts[i]);
725
+
726
+ if (flags.is_whitespace) {
727
+ //NOTE: C++ std::regex \s does not mach 0x85, Rust and Python regex does.
728
+ //text_collapsed[i] = (char) 0x85; // <Next Line> as whitespace fallback
729
+ text_collapsed[i] = (char) 0x0B; // <vertical tab> as whitespace fallback
730
+ } else if (k_ucat_cpt.find(flags.category_flag()) != k_ucat_cpt.end()) {
731
+ text_collapsed[i] = k_ucat_cpt.at(flags.category_flag());
732
+ } else {
733
+ text_collapsed[i] = (char) 0xD0; // fallback
734
+ }
735
+ }
736
+ }
737
+
738
+ std::vector<size_t> bpe_offsets = { cpts.size() };
739
+
740
+ for (const auto & regex_expr : regex_exprs) {
741
+ // first, see if we have an efficient custom regex implementation
742
+ auto tmp = unicode_regex_split_custom(text, regex_expr, bpe_offsets);
743
+
744
+ if (!tmp.empty()) {
745
+ bpe_offsets = std::move(tmp);
746
+ continue;
747
+ }
748
+
749
+ // fallback to general-purpose std::regex / std::wregex
750
+ try {
751
+ // if a unicode category is used in the regex, we use the collapsed text and replace the unicode category
752
+ // with the corresponding collapsed representation
753
+ bool use_collapsed = false;
754
+ for (const auto & ucat : k_ucat_enum) {
755
+ if (std::string::npos != regex_expr.find(ucat.first)) {
756
+ use_collapsed = true;
757
+ break;
758
+ }
759
+ }
760
+
761
+ if (use_collapsed) {
762
+ // sanity-check that the original regex does not contain any non-ASCII characters
763
+ const auto cpts_regex = unicode_cpts_from_utf8(regex_expr);
764
+ for (size_t i = 0; i < cpts_regex.size(); ++i) {
765
+ if (cpts_regex[i] >= 128) {
766
+ throw std::runtime_error("Regex includes both unicode categories and non-ASCII characters - not supported");
767
+ }
768
+ }
769
+
770
+ // generate a collapsed representation of the regex
771
+ std::string regex_expr_collapsed;
772
+
773
+ // track if we are inside [], because nested [] are not allowed
774
+ bool inside = false;
775
+ for (size_t i = 0; i < regex_expr.size(); ++i) {
776
+ if (regex_expr[i] == '[' && (i == 0 || regex_expr[i - 1] != '\\')) {
777
+ regex_expr_collapsed += '[';
778
+ inside = true;
779
+ continue;
780
+ }
781
+
782
+ if (inside && regex_expr[i] == ']' && regex_expr[i - 1] != '\\') {
783
+ regex_expr_collapsed += ']';
784
+ inside = false;
785
+ continue;
786
+ }
787
+
788
+ if (regex_expr[i + 0] == '\\' && i + 4 < regex_expr.size() &&
789
+ regex_expr[i + 1] == 'p' &&
790
+ regex_expr[i + 2] == '{' &&
791
+ regex_expr[i + 4] == '}') {
792
+ const std::string pat = regex_expr.substr(i, 5);
793
+ if (k_ucat_enum.find(pat) != k_ucat_enum.end()) {
794
+ if (!inside) {
795
+ regex_expr_collapsed += '[';
796
+ }
797
+ regex_expr_collapsed += k_ucat_cpt.at(k_ucat_enum.at(pat));
798
+ regex_expr_collapsed += k_ucat_map.at(k_ucat_enum.at(pat));
799
+ if (!inside) {
800
+ regex_expr_collapsed += ']';
801
+ }
802
+ i += 4;
803
+ continue;
804
+ }
805
+ }
806
+
807
+ regex_expr_collapsed += regex_expr[i];
808
+ }
809
+
810
+ //printf("text_collapsed: %s\n", text_collapsed.c_str());
811
+ //printf("regex_expr_collapsed: %s\n", regex_expr_collapsed.c_str());
812
+ bpe_offsets = unicode_regex_split_stl(text_collapsed, regex_expr_collapsed, bpe_offsets);
813
+ } else {
814
+ // no unicode category used, we can use std::wregex directly
815
+ const std::wstring wregex_expr = unicode_wstring_from_utf8(regex_expr);
816
+
817
+ // std::wregex \s does not mach non-ASCII whitespaces, using 0x0B as fallback
818
+ std::wstring wtext(cpts.begin(), cpts.end());
819
+ for (size_t i = 0; i < wtext.size(); ++i) {
820
+ if (wtext[i] > 0x7F && unicode_cpt_flags_from_cpt(wtext[i]).is_whitespace) {
821
+ wtext[i] = 0x0B;
822
+ }
823
+ }
824
+
825
+ //printf("text: %s\n", text.c_str());
826
+ //printf("regex_expr: %s\n", regex_expr.c_str());
827
+ bpe_offsets = unicode_regex_split_stl(wtext, wregex_expr, bpe_offsets);
828
+ }
829
+ } catch (std::regex_error & e) {
830
+ fprintf(stderr, "Failed to process regex: '%s'\n", regex_expr.c_str());
831
+ fprintf(stderr, "Regex error: %s\n", e.what());
832
+ throw std::runtime_error("Failed to process regex");
833
+ }
834
+ }
835
+
836
+ std::vector<std::string> bpe_words;
837
+ bpe_words.reserve(bpe_offsets.size()); // reserve memory for the approximate size
838
+
839
+ size_t start = 0;
840
+ for (size_t & offset : bpe_offsets) {
841
+ bpe_words.emplace_back();
842
+ for (size_t i = start; i < start + offset; ++i) {
843
+ bpe_words.back() += unicode_cpt_to_utf8(cpts[i]);
844
+ }
845
+ start += offset;
846
+ }
847
+
848
+ return unicode_byte_encoding_process(bpe_words);
849
+ }