@fugood/llama.node 0.5.0 → 0.6.1

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 (37) hide show
  1. package/CMakeLists.txt +40 -5
  2. package/bin/darwin/arm64/llama-node.node +0 -0
  3. package/bin/darwin/x64/llama-node.node +0 -0
  4. package/bin/linux/arm64/llama-node.node +0 -0
  5. package/bin/linux/x64/llama-node.node +0 -0
  6. package/bin/linux-cuda/arm64/llama-node.node +0 -0
  7. package/bin/linux-cuda/x64/llama-node.node +0 -0
  8. package/bin/linux-vulkan/arm64/llama-node.node +0 -0
  9. package/bin/linux-vulkan/x64/llama-node.node +0 -0
  10. package/bin/win32/x64/llama-node.node +0 -0
  11. package/bin/win32/x64/node.lib +0 -0
  12. package/bin/win32-vulkan/arm64/llama-node.node +0 -0
  13. package/bin/win32-vulkan/arm64/node.lib +0 -0
  14. package/bin/win32-vulkan/x64/llama-node.node +0 -0
  15. package/bin/win32-vulkan/x64/node.lib +0 -0
  16. package/lib/binding.ts +46 -0
  17. package/lib/index.js +18 -0
  18. package/lib/index.ts +24 -0
  19. package/package.json +4 -1
  20. package/patches/node-api-headers+1.1.0.patch +26 -0
  21. package/src/DecodeAudioTokenWorker.cpp +40 -0
  22. package/src/DecodeAudioTokenWorker.h +22 -0
  23. package/src/EmbeddingWorker.cpp +7 -5
  24. package/src/LlamaCompletionWorker.cpp +64 -50
  25. package/src/LlamaCompletionWorker.h +6 -7
  26. package/src/LlamaContext.cpp +523 -224
  27. package/src/LlamaContext.h +25 -4
  28. package/src/LoadSessionWorker.cpp +4 -2
  29. package/src/SaveSessionWorker.cpp +10 -6
  30. package/src/TokenizeWorker.cpp +10 -5
  31. package/src/addons.cc +8 -11
  32. package/src/common.hpp +92 -93
  33. package/src/tts_utils.cpp +346 -0
  34. package/src/tts_utils.h +62 -0
  35. package/src/win_dynamic_load.c +2102 -0
  36. package/bin/win32/arm64/llama-node.node +0 -0
  37. package/bin/win32/arm64/node.lib +0 -0
@@ -0,0 +1,346 @@
1
+ #include "tts_utils.h"
2
+
3
+ using json = nlohmann::json;
4
+
5
+ std::string audio_text_from_speaker(json speaker,
6
+ const tts_type type = OUTETTS_V0_2) {
7
+ std::string audio_text = "<|text_start|>";
8
+
9
+ if (type == OUTETTS_V0_2 || type == OUTETTS_V0_3) {
10
+ std::string separator =
11
+ (type == OUTETTS_V0_3) ? "<|space|>" : "<|text_sep|>";
12
+ for (const auto &word : speaker["words"]) {
13
+ audio_text += word["word"].get<std::string>() + separator;
14
+ }
15
+ }
16
+
17
+ return audio_text;
18
+ }
19
+
20
+ std::string audio_data_from_speaker(json speaker,
21
+ const tts_type type = OUTETTS_V0_2) {
22
+ std::string audio_data = "<|audio_start|>\n";
23
+
24
+ if (type == OUTETTS_V0_2 || type == OUTETTS_V0_3) {
25
+ std::string code_start = (type == OUTETTS_V0_3) ? "" : "<|code_start|>";
26
+ std::string code_end =
27
+ (type == OUTETTS_V0_3) ? "<|space|>" : "<|code_end|>";
28
+ for (const auto &word : speaker["words"]) {
29
+ std::string word_text = word["word"].get<std::string>();
30
+ double duration = word["duration"].get<double>();
31
+ std::vector<int> codes = word["codes"].get<std::vector<int>>();
32
+
33
+ // Create the audio output entry
34
+ std::ostringstream word_entry;
35
+ word_entry << word_text << "<|t_" << std::fixed << std::setprecision(2)
36
+ << duration << "|>" + code_start;
37
+ for (const auto &Code : codes) {
38
+ word_entry << "<|" << Code << "|>";
39
+ }
40
+ word_entry << code_end << "\n";
41
+ audio_data += word_entry.str();
42
+ }
43
+ }
44
+
45
+ return audio_data;
46
+ }
47
+
48
+ static const std::map<int, std::string> ones = {
49
+ {0, "zero"}, {1, "one"}, {2, "two"}, {3, "three"},
50
+ {4, "four"}, {5, "five"}, {6, "six"}, {7, "seven"},
51
+ {8, "eight"}, {9, "nine"}, {10, "ten"}, {11, "eleven"},
52
+ {12, "twelve"}, {13, "thirteen"}, {14, "fourteen"}, {15, "fifteen"},
53
+ {16, "sixteen"}, {17, "seventeen"}, {18, "eighteen"}, {19, "nineteen"}};
54
+
55
+ static const std::map<int, std::string> tens = {
56
+ {2, "twenty"}, {3, "thirty"}, {4, "forty"}, {5, "fifty"},
57
+ {6, "sixty"}, {7, "seventy"}, {8, "eighty"}, {9, "ninety"}};
58
+
59
+ // Convert a number less than 1000 to words
60
+ std::string convert_less_than_thousand(int num) {
61
+ std::string result;
62
+
63
+ if (num >= 100) {
64
+ result += ones.at(num / 100) + " hundred ";
65
+ num %= 100;
66
+ }
67
+
68
+ if (num >= 20) {
69
+ result += tens.at(num / 10);
70
+ if (num % 10 > 0) {
71
+ result += "-" + ones.at(num % 10);
72
+ }
73
+ } else if (num > 0) {
74
+ result += ones.at(num);
75
+ }
76
+
77
+ return result;
78
+ }
79
+
80
+ std::string number_to_words(const std::string &number_str) {
81
+ try {
82
+ size_t decimal_pos = number_str.find('.');
83
+ std::string integer_part = number_str.substr(0, decimal_pos);
84
+
85
+ int int_number = std::stoi(integer_part);
86
+ std::string result;
87
+
88
+ if (int_number == 0) {
89
+ result = "zero";
90
+ } else {
91
+ if (int_number >= 1000000000) {
92
+ int billions = int_number / 1000000000;
93
+ result += convert_less_than_thousand(billions) + " billion ";
94
+ int_number %= 1000000000;
95
+ }
96
+
97
+ if (int_number >= 1000000) {
98
+ int millions = int_number / 1000000;
99
+ result += convert_less_than_thousand(millions) + " million ";
100
+ int_number %= 1000000;
101
+ }
102
+
103
+ if (int_number >= 1000) {
104
+ int thousands = int_number / 1000;
105
+ result += convert_less_than_thousand(thousands) + " thousand ";
106
+ int_number %= 1000;
107
+ }
108
+
109
+ if (int_number > 0) {
110
+ result += convert_less_than_thousand(int_number);
111
+ }
112
+ }
113
+
114
+ // Handle decimal part
115
+ if (decimal_pos != std::string::npos) {
116
+ result += " point";
117
+ std::string decimal_part = number_str.substr(decimal_pos + 1);
118
+ for (char digit : decimal_part) {
119
+ result += " " + ones.at(digit - '0');
120
+ }
121
+ }
122
+
123
+ return result;
124
+ } catch (const std::exception &e) {
125
+ // Skip if fails
126
+ return " ";
127
+ }
128
+ }
129
+
130
+ std::string replace_numbers_with_words(const std::string &input_text) {
131
+ std::regex number_pattern(R"(\d+(\.\d+)?)");
132
+ std::string result;
133
+ auto it = std::sregex_iterator(input_text.begin(), input_text.end(),
134
+ number_pattern);
135
+ auto end = std::sregex_iterator();
136
+
137
+ size_t last_pos = 0;
138
+ for (std::sregex_iterator i = it; i != end; ++i) {
139
+ const std::smatch &match = *i;
140
+ result.append(input_text, last_pos, match.position() - last_pos);
141
+ result.append(number_to_words(match.str()));
142
+ last_pos = match.position() + match.length();
143
+ }
144
+ result.append(input_text, last_pos);
145
+
146
+ return result;
147
+ }
148
+
149
+ // Based on:
150
+ // https://github.com/edwko/OuteTTS/blob/a613e79c489d8256dd657ea9168d78de75895d82/outetts/version/v1/prompt_processor.py#L39
151
+ std::string process_text(const std::string &text,
152
+ const tts_type tts_type = OUTETTS_V0_2) {
153
+
154
+ // For now I skipped text romanization as I am unsure how to handle
155
+ // uroman and MeCab implementations in C++
156
+ // maybe something like https://github.com/anyascii/anyascii/ could work.
157
+ // currently only English would be supported in this function
158
+
159
+ std::string processed_text = replace_numbers_with_words(text);
160
+
161
+ std::transform(processed_text.begin(), processed_text.end(),
162
+ processed_text.begin(), ::tolower);
163
+
164
+ std::regex special_chars(R"([-_/,\.\\])");
165
+ processed_text = std::regex_replace(processed_text, special_chars, " ");
166
+
167
+ std::regex non_alpha(R"([^a-z\s])");
168
+ processed_text = std::regex_replace(processed_text, non_alpha, "");
169
+
170
+ std::regex multiple_spaces(R"(\s+)");
171
+ processed_text = std::regex_replace(processed_text, multiple_spaces, " ");
172
+
173
+ processed_text =
174
+ std::regex_replace(processed_text, std::regex(R"(^\s+|\s+$)"), "");
175
+
176
+ /*
177
+ Replace spaces with the separator token same as in line 365
178
+
179
+ for (auto & c : prompt_user) {
180
+ if (c == ' ') {
181
+ prompt_clean += "<|text_sep|>";
182
+ */
183
+ std::string separator =
184
+ (tts_type == OUTETTS_V0_3) ? "<|space|>" : "<|text_sep|>";
185
+ processed_text =
186
+ std::regex_replace(processed_text, std::regex(R"(\s)"), separator);
187
+
188
+ return processed_text;
189
+ }
190
+
191
+ #ifdef _WIN32
192
+ #define M_PI 3.14159265358979323846
193
+ #endif
194
+
195
+ void fill_hann_window(int length, bool periodic, float *output) {
196
+ int offset = -1;
197
+ if (periodic) {
198
+ offset = 0;
199
+ }
200
+ for (int i = 0; i < length; i++) {
201
+ output[i] = 0.5 * (1.0 - cosf((2.0 * M_PI * i) / (length + offset)));
202
+ }
203
+ }
204
+
205
+ void twiddle(float *real, float *imag, int k, int N) {
206
+ float angle = 2 * M_PI * k / N;
207
+ *real = cos(angle);
208
+ *imag = sin(angle);
209
+ }
210
+
211
+ void irfft(int n, const float *inp_cplx, float *out_real) {
212
+ int N = n / 2 + 1;
213
+
214
+ std::vector<float> real_input(N);
215
+ std::vector<float> imag_input(N);
216
+ for (int i = 0; i < N; ++i) {
217
+ real_input[i] = inp_cplx[2 * i];
218
+ imag_input[i] = inp_cplx[2 * i + 1];
219
+ }
220
+
221
+ std::vector<float> real_output(n);
222
+ std::vector<float> imag_output(n);
223
+
224
+ for (int k = 0; k < n; ++k) {
225
+ real_output[k] = 0.0f;
226
+ imag_output[k] = 0.0f;
227
+ for (int m = 0; m < N; ++m) {
228
+ float twiddle_real;
229
+ float twiddle_imag;
230
+
231
+ twiddle(&twiddle_real, &twiddle_imag, k * m, n);
232
+
233
+ real_output[k] +=
234
+ real_input[m] * twiddle_real - imag_input[m] * twiddle_imag;
235
+ imag_output[k] +=
236
+ real_input[m] * twiddle_imag + imag_input[m] * twiddle_real;
237
+ }
238
+ }
239
+
240
+ for (int i = 0; i < n; ++i) {
241
+ out_real[i] = real_output[i] / N;
242
+ }
243
+ }
244
+
245
+ void fold(const std::vector<float> &data, int64_t n_out, int64_t n_win,
246
+ int64_t n_hop, int64_t n_pad, std::vector<float> &output) {
247
+ int64_t output_height = n_out;
248
+ int64_t kernel_w = n_win;
249
+ int64_t stride_w = n_hop;
250
+ int64_t width = n_out;
251
+
252
+ output.resize(width, 0.0f);
253
+
254
+ int64_t col_idx = 0;
255
+ for (int64_t w_col = 0; w_col < width; ++w_col) {
256
+ int64_t start = w_col * stride_w - n_pad;
257
+ int64_t end = start + kernel_w;
258
+
259
+ for (int64_t w_im = start; w_im < end; ++w_im) {
260
+ if (w_im >= 0 && w_im < output_height && col_idx < (int64_t)data.size()) {
261
+ output[w_im] += data[col_idx];
262
+ }
263
+ col_idx++;
264
+ }
265
+ }
266
+
267
+ output.resize(n_out - 2 * n_pad);
268
+ }
269
+
270
+ std::vector<float> embd_to_audio(const float *embd, const int n_codes,
271
+ const int n_embd, const int n_thread) {
272
+ const int n_fft = 1280;
273
+ const int n_hop = 320;
274
+ const int n_win = 1280;
275
+ const int n_pad = (n_win - n_hop) / 2;
276
+ const int n_out = (n_codes - 1) * n_hop + n_win;
277
+
278
+ std::vector<float> hann(n_fft);
279
+
280
+ fill_hann_window(hann.size(), true, hann.data());
281
+
282
+ int n_spec = n_embd * n_codes;
283
+
284
+ std::vector<float> E(n_spec);
285
+ std::vector<float> S(n_spec);
286
+ std::vector<float> ST(n_spec);
287
+
288
+ for (int l = 0; l < n_codes; ++l) {
289
+ for (int k = 0; k < n_embd; ++k) {
290
+ E[k * n_codes + l] = embd[l * n_embd + k];
291
+ }
292
+ }
293
+
294
+ for (int k = 0; k < n_embd / 2; ++k) {
295
+ for (int l = 0; l < n_codes; ++l) {
296
+ float mag = E[(k)*n_codes + l];
297
+ float phi = E[(k + n_embd / 2) * n_codes + l];
298
+
299
+ mag = exp(mag);
300
+
301
+ if (mag > 1e2) {
302
+ mag = 1e2;
303
+ }
304
+ S[2 * (k * n_codes + l) + 0] = mag * cosf(phi);
305
+ S[2 * (k * n_codes + l) + 1] = mag * sinf(phi);
306
+ }
307
+ }
308
+
309
+ for (int l = 0; l < n_codes; ++l) {
310
+ for (int k = 0; k < n_embd / 2; ++k) {
311
+ ST[l * n_embd + 2 * k + 0] = S[2 * (k * n_codes + l) + 0];
312
+ ST[l * n_embd + 2 * k + 1] = S[2 * (k * n_codes + l) + 1];
313
+ }
314
+ }
315
+
316
+ std::vector<float> res(n_codes * n_fft);
317
+ std::vector<float> hann2(n_codes * n_fft);
318
+
319
+ std::vector<std::thread> workers(n_thread);
320
+ for (int i = 0; i < n_thread; ++i) {
321
+ workers[i] = std::thread([&, i]() {
322
+ for (int l = i; l < n_codes; l += n_thread) {
323
+ irfft(n_fft, ST.data() + l * n_embd, res.data() + l * n_fft);
324
+ for (int j = 0; j < n_fft; ++j) {
325
+ res[l * n_fft + j] *= hann[j];
326
+ hann2[l * n_fft + j] = hann[j] * hann[j];
327
+ }
328
+ }
329
+ });
330
+ }
331
+ for (int i = 0; i < n_thread; ++i) {
332
+ workers[i].join();
333
+ }
334
+
335
+ std::vector<float> audio;
336
+ std::vector<float> env;
337
+
338
+ fold(res, n_out, n_win, n_hop, n_pad, audio);
339
+ fold(hann2, n_out, n_win, n_hop, n_pad, env); // TODO: can be done once
340
+
341
+ for (size_t i = 0; i < audio.size(); ++i) {
342
+ audio[i] /= env[i];
343
+ }
344
+
345
+ return audio;
346
+ }
@@ -0,0 +1,62 @@
1
+ #pragma once
2
+
3
+ #include <regex>
4
+ #include <sstream>
5
+ #include <string>
6
+ #include <thread>
7
+ #include <vector>
8
+
9
+ #include "json.hpp"
10
+
11
+ enum tts_type { UNKNOWN = -1, OUTETTS_V0_2 = 1, OUTETTS_V0_3 = 2 };
12
+
13
+ std::string audio_text_from_speaker(nlohmann::json speaker,
14
+ const tts_type type);
15
+ std::string audio_data_from_speaker(nlohmann::json speaker,
16
+ const tts_type type);
17
+ std::string process_text(const std::string &text, const tts_type tts_type);
18
+ std::vector<float> embd_to_audio(const float *embd, const int n_codes,
19
+ const int n_embd, const int n_thread);
20
+
21
+ // the default speaker profile is from:
22
+ // https://github.com/edwko/OuteTTS/blob/main/outetts/version/v1/default_speakers/en_male_1.json
23
+ static const char *DEFAULT_AUDIO_TEXT =
24
+ "<|text_start|>the<|text_sep|>overall<|text_sep|>package<|text_sep|>from<|"
25
+ "text_sep|>just<|text_sep|>two<|text_sep|>people<|text_sep|>is<|text_sep|>"
26
+ "pretty<|text_sep|>remarkable<|text_sep|>sure<|text_sep|>i<|text_sep|>have<"
27
+ "|text_sep|>some<|text_sep|>critiques<|text_sep|>about<|text_sep|>some<|"
28
+ "text_sep|>of<|text_sep|>the<|text_sep|>gameplay<|text_sep|>aspects<|text_"
29
+ "sep|>but<|text_sep|>its<|text_sep|>still<|text_sep|>really<|text_sep|>"
30
+ "enjoyable<|text_sep|>and<|text_sep|>it<|text_sep|>looks<|text_sep|>lovely<"
31
+ "|text_sep|>";
32
+ static const char *DEFAULT_AUDIO_DATA = R"(<|audio_start|>
33
+ the<|t_0.08|><|code_start|><|257|><|740|><|636|><|913|><|788|><|1703|><|code_end|>
34
+ overall<|t_0.36|><|code_start|><|127|><|201|><|191|><|774|><|700|><|532|><|1056|><|557|><|798|><|298|><|1741|><|747|><|1662|><|1617|><|1702|><|1527|><|368|><|1588|><|1049|><|1008|><|1625|><|747|><|1576|><|728|><|1019|><|1696|><|1765|><|code_end|>
35
+ package<|t_0.56|><|code_start|><|935|><|584|><|1319|><|627|><|1016|><|1491|><|1344|><|1117|><|1526|><|1040|><|239|><|1435|><|951|><|498|><|723|><|1180|><|535|><|789|><|1649|><|1637|><|78|><|465|><|1668|><|901|><|595|><|1675|><|117|><|1009|><|1667|><|320|><|840|><|79|><|507|><|1762|><|1508|><|1228|><|1768|><|802|><|1450|><|1457|><|232|><|639|><|code_end|>
36
+ from<|t_0.19|><|code_start|><|604|><|782|><|1682|><|872|><|1532|><|1600|><|1036|><|1761|><|647|><|1554|><|1371|><|653|><|1595|><|950|><|code_end|>
37
+ just<|t_0.25|><|code_start|><|1782|><|1670|><|317|><|786|><|1748|><|631|><|599|><|1155|><|1364|><|1524|><|36|><|1591|><|889|><|1535|><|541|><|440|><|1532|><|50|><|870|><|code_end|>
38
+ two<|t_0.24|><|code_start|><|1681|><|1510|><|673|><|799|><|805|><|1342|><|330|><|519|><|62|><|640|><|1138|><|565|><|1552|><|1497|><|1552|><|572|><|1715|><|1732|><|code_end|>
39
+ people<|t_0.39|><|code_start|><|593|><|274|><|136|><|740|><|691|><|633|><|1484|><|1061|><|1138|><|1485|><|344|><|428|><|397|><|1562|><|645|><|917|><|1035|><|1449|><|1669|><|487|><|442|><|1484|><|1329|><|1832|><|1704|><|600|><|761|><|653|><|269|><|code_end|>
40
+ is<|t_0.16|><|code_start|><|566|><|583|><|1755|><|646|><|1337|><|709|><|802|><|1008|><|485|><|1583|><|652|><|10|><|code_end|>
41
+ pretty<|t_0.32|><|code_start|><|1818|><|1747|><|692|><|733|><|1010|><|534|><|406|><|1697|><|1053|><|1521|><|1355|><|1274|><|816|><|1398|><|211|><|1218|><|817|><|1472|><|1703|><|686|><|13|><|822|><|445|><|1068|><|code_end|>
42
+ remarkable<|t_0.68|><|code_start|><|230|><|1048|><|1705|><|355|><|706|><|1149|><|1535|><|1787|><|1356|><|1396|><|835|><|1583|><|486|><|1249|><|286|><|937|><|1076|><|1150|><|614|><|42|><|1058|><|705|><|681|><|798|><|934|><|490|><|514|><|1399|><|572|><|1446|><|1703|><|1346|><|1040|><|1426|><|1304|><|664|><|171|><|1530|><|625|><|64|><|1708|><|1830|><|1030|><|443|><|1509|><|1063|><|1605|><|1785|><|721|><|1440|><|923|><|code_end|>
43
+ sure<|t_0.36|><|code_start|><|792|><|1780|><|923|><|1640|><|265|><|261|><|1525|><|567|><|1491|><|1250|><|1730|><|362|><|919|><|1766|><|543|><|1|><|333|><|113|><|970|><|252|><|1606|><|133|><|302|><|1810|><|1046|><|1190|><|1675|><|code_end|>
44
+ i<|t_0.08|><|code_start|><|123|><|439|><|1074|><|705|><|1799|><|637|><|code_end|>
45
+ have<|t_0.16|><|code_start|><|1509|><|599|><|518|><|1170|><|552|><|1029|><|1267|><|864|><|419|><|143|><|1061|><|0|><|code_end|>
46
+ some<|t_0.16|><|code_start|><|619|><|400|><|1270|><|62|><|1370|><|1832|><|917|><|1661|><|167|><|269|><|1366|><|1508|><|code_end|>
47
+ critiques<|t_0.60|><|code_start|><|559|><|584|><|1163|><|1129|><|1313|><|1728|><|721|><|1146|><|1093|><|577|><|928|><|27|><|630|><|1080|><|1346|><|1337|><|320|><|1382|><|1175|><|1682|><|1556|><|990|><|1683|><|860|><|1721|><|110|><|786|><|376|><|1085|><|756|><|1523|><|234|><|1334|><|1506|><|1578|><|659|><|612|><|1108|><|1466|><|1647|><|308|><|1470|><|746|><|556|><|1061|><|code_end|>
48
+ about<|t_0.29|><|code_start|><|26|><|1649|><|545|><|1367|><|1263|><|1728|><|450|><|859|><|1434|><|497|><|1220|><|1285|><|179|><|755|><|1154|><|779|><|179|><|1229|><|1213|><|922|><|1774|><|1408|><|code_end|>
49
+ some<|t_0.23|><|code_start|><|986|><|28|><|1649|><|778|><|858|><|1519|><|1|><|18|><|26|><|1042|><|1174|><|1309|><|1499|><|1712|><|1692|><|1516|><|1574|><|code_end|>
50
+ of<|t_0.07|><|code_start|><|197|><|716|><|1039|><|1662|><|64|><|code_end|>
51
+ the<|t_0.08|><|code_start|><|1811|><|1568|><|569|><|886|><|1025|><|1374|><|code_end|>
52
+ gameplay<|t_0.48|><|code_start|><|1269|><|1092|><|933|><|1362|><|1762|><|1700|><|1675|><|215|><|781|><|1086|><|461|><|838|><|1022|><|759|><|649|><|1416|><|1004|><|551|><|909|><|787|><|343|><|830|><|1391|><|1040|><|1622|><|1779|><|1360|><|1231|><|1187|><|1317|><|76|><|997|><|989|><|978|><|737|><|189|><|code_end|>
53
+ aspects<|t_0.56|><|code_start|><|1423|><|797|><|1316|><|1222|><|147|><|719|><|1347|><|386|><|1390|><|1558|><|154|><|440|><|634|><|592|><|1097|><|1718|><|712|><|763|><|1118|><|1721|><|1311|><|868|><|580|><|362|><|1435|><|868|><|247|><|221|><|886|><|1145|><|1274|><|1284|><|457|><|1043|><|1459|><|1818|><|62|><|599|><|1035|><|62|><|1649|><|778|><|code_end|>
54
+ but<|t_0.20|><|code_start|><|780|><|1825|><|1681|><|1007|><|861|><|710|><|702|><|939|><|1669|><|1491|><|613|><|1739|><|823|><|1469|><|648|><|code_end|>
55
+ its<|t_0.09|><|code_start|><|92|><|688|><|1623|><|962|><|1670|><|527|><|599|><|code_end|>
56
+ still<|t_0.27|><|code_start|><|636|><|10|><|1217|><|344|><|713|><|957|><|823|><|154|><|1649|><|1286|><|508|><|214|><|1760|><|1250|><|456|><|1352|><|1368|><|921|><|615|><|5|><|code_end|>
57
+ really<|t_0.36|><|code_start|><|55|><|420|><|1008|><|1659|><|27|><|644|><|1266|><|617|><|761|><|1712|><|109|><|1465|><|1587|><|503|><|1541|><|619|><|197|><|1019|><|817|><|269|><|377|><|362|><|1381|><|507|><|1488|><|4|><|1695|><|code_end|>
58
+ enjoyable<|t_0.49|><|code_start|><|678|><|501|><|864|><|319|><|288|><|1472|><|1341|><|686|><|562|><|1463|><|619|><|1563|><|471|><|911|><|730|><|1811|><|1006|><|520|><|861|><|1274|><|125|><|1431|><|638|><|621|><|153|><|876|><|1770|><|437|><|987|><|1653|><|1109|><|898|><|1285|><|80|><|593|><|1709|><|843|><|code_end|>
59
+ and<|t_0.15|><|code_start|><|1285|><|987|><|303|><|1037|><|730|><|1164|><|502|><|120|><|1737|><|1655|><|1318|><|code_end|>
60
+ it<|t_0.09|><|code_start|><|848|><|1366|><|395|><|1601|><|1513|><|593|><|1302|><|code_end|>
61
+ looks<|t_0.27|><|code_start|><|1281|><|1266|><|1755|><|572|><|248|><|1751|><|1257|><|695|><|1380|><|457|><|659|><|585|><|1315|><|1105|><|1776|><|736|><|24|><|736|><|654|><|1027|><|code_end|>
62
+ lovely<|t_0.56|><|code_start|><|634|><|596|><|1766|><|1556|><|1306|><|1285|><|1481|><|1721|><|1123|><|438|><|1246|><|1251|><|795|><|659|><|1381|><|1658|><|217|><|1772|><|562|><|952|><|107|><|1129|><|1112|><|467|><|550|><|1079|><|840|><|1615|><|1469|><|1380|><|168|><|917|><|836|><|1827|><|437|><|583|><|67|><|595|><|1087|><|1646|><|1493|><|1677|><|code_end|>)";