{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[97, 121, 121, 121, 121, 32, 119, 104, 97, 116, 115, 32, 117, 112, 32, 128075]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[ord(x) for x in \"ayyyy whats up 👋\"]" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[97,\n", " 121,\n", " 121,\n", " 121,\n", " 121,\n", " 32,\n", " 119,\n", " 104,\n", " 97,\n", " 116,\n", " 115,\n", " 32,\n", " 117,\n", " 112,\n", " 32,\n", " 240,\n", " 159,\n", " 145,\n", " 139]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(\"ayyyy whats up 👋\".encode('utf-8'))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def get_counts(text):\n", " counts = {}\n", " for pairs in zip(text, text[1:]):\n", " counts[pairs] = counts.get(pairs, 0) + 1\n", " return counts\n", "\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('y', 'y'), 3)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "counts = get_counts(\"ayyyy whats up 👋\")\n", "top_pair = max(counts, key=counts.get)\n", "top_pair, counts[top_pair]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "((121, 121), 3)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "counts = get_counts(\"ayyyy whats up 👋\".encode('utf-8'))\n", "top_pair = max(counts, key=counts.get)\n", "top_pair, counts[top_pair]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[97,\n", " 69420,\n", " 69420,\n", " 32,\n", " 119,\n", " 104,\n", " 97,\n", " 116,\n", " 115,\n", " 32,\n", " 117,\n", " 112,\n", " 32,\n", " 240,\n", " 159,\n", " 145,\n", " 139]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def merge_token(token_pattern, text, symbol):\n", " i = 0\n", " new_text = []\n", " while i < len(text):\n", " if i + 1 < len(text) and text[i] == token_pattern[0] and text[i+1] == token_pattern[1]:\n", " new_text.append(symbol)\n", " i += 2\n", " else:\n", " new_text.append(text[i])\n", " i += 1\n", " return new_text\n", "\n", "new_text = merge_token(top_pair, \"ayyyy whats up 👋\".encode('utf-8'), 69420)\n", "\n", "new_text\n", " " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I’ve been on the low\n", "\n", "I been taking my time\n", "I feel\n", "[73, 226, 128, 153, 118, 101, 32, 98, 101, 101, 110, 32, 111, 110, 32, 116, 104, 101, 32, 108, 111, 119, 10, 10, 73, 32, 98, 101, 101, 110, 32, 116, 97, 107, 105, 110, 103, 32, 109, 121, 32, 116, 105, 109, 101, 10, 73, 32, 102, 101]\n", "merged (101, 32) to 256\n", "merged (116, 32) to 257\n", "merged (116, 104) to 258\n", "merged (105, 110) to 259\n", "merged (44, 32) to 260\n", "merged (115, 32) to 261\n", "merged (111, 117) to 262\n", "merged (121, 32) to 263\n", "merged (101, 114) to 264\n", "merged (100, 32) to 265\n", "merged (97, 110) to 266\n", "merged (73, 32) to 267\n", "merged (32, 258) to 268\n", "merged (97, 32) to 269\n", "merged (111, 110) to 270\n", "merged (259, 39) to 271\n", "merged (111, 119) to 272\n", "merged (111, 32) to 273\n", "merged (108, 105) to 274\n", "merged (108, 108) to 275\n", "merged (99, 107) to 276\n", "merged (101, 97) to 277\n", "merged (121, 262) to 278\n", "merged (111, 114) to 279\n", "merged (101, 110) to 280\n", "merged (268, 256) to 281\n", "merged (271, 32) to 282\n", "merged (109, 32) to 283\n", "merged (101, 10) to 284\n", "merged (32, 109) to 285\n", "merged (104, 97) to 286\n", "merged (105, 116) to 287\n", "merged (73, 39) to 288\n", "merged (107, 256) to 289\n", "merged (259, 103) to 290\n", "merged (117, 115) to 291\n", "merged (101, 101) to 292\n", "merged (226, 128) to 293\n", "merged (118, 264) to 294\n", "merged (110, 272) to 295\n", "merged (105, 103) to 296\n", "merged (105, 261) to 297\n", "merged (278, 32) to 298\n", "merged (280, 32) to 299\n", "merged (105, 257) to 300\n", "merged (116, 273) to 301\n", "merged (115, 116) to 302\n", "merged (115, 104) to 303\n", "merged (274, 289) to 304\n", "merged (288, 283) to 305\n", "merged (99, 104) to 306\n", "merged (118, 256) to 307\n", "merged (108, 97) to 308\n", "merged (293, 153) to 309\n", "merged (266, 265) to 310\n", "merged (111, 100) to 311\n", "merged (10, 267) to 312\n", "merged (117, 276) to 313\n", "merged (258, 256) to 314\n", "merged (114, 97) to 315\n", "merged (101, 115) to 316\n", "merged (116, 105) to 317\n", "merged (102, 279) to 318\n", "merged (107, 295) to 319\n", "merged (109, 256) to 320\n", "merged (101, 294) to 321\n", "merged (97, 257) to 322\n", "merged (98, 101) to 323\n", "merged (97, 275) to 324\n", "merged (101, 257) to 325\n", "merged (117, 257) to 326\n", "merged (114, 111) to 327\n", "merged (41, 10) to 328\n", "merged (102, 313) to 329\n", "merged (119, 104) to 330\n", "merged (296, 104) to 331\n", "merged (290, 32) to 332\n", "merged (119, 105) to 333\n", "merged (100, 270) to 334\n", "merged (101, 260) to 335\n", "merged (103, 111) to 336\n", "merged (264, 32) to 337\n", "merged (109, 263) to 338\n", "merged (105, 99) to 339\n", "merged (97, 114) to 340\n", "merged (39, 261) to 341\n", "merged (111, 102) to 342\n", "merged (110, 269) to 343\n", "merged (117, 112) to 344\n", "merged (285, 263) to 345\n", "merged (97, 116) to 346\n", "merged (97, 261) to 347\n", "merged (266, 32) to 348\n", "merged (260, 267) to 349\n", "merged (115, 10) to 350\n", "merged (101, 265) to 351\n", "merged (108, 32) to 352\n", "merged (119, 266) to 353\n", "merged (110, 265) to 354\n", "merged (333, 258) to 355\n", "merged (108, 111) to 356\n", "merged (276, 32) to 357\n", "merged (100, 10) to 358\n", "merged (272, 32) to 359\n", "merged (114, 32) to 360\n", "merged (102, 292) to 361\n", "merged (98, 256) to 362\n", "merged (111, 109) to 363\n", "merged (39, 257) to 364\n", "merged (101, 263) to 365\n", "merged (319, 32) to 366\n", "merged (98, 311) to 367\n", "merged (291, 257) to 368\n", "merged (116, 10) to 369\n", "merged (98, 97) to 370\n", "merged (323, 299) to 371\n", "merged (367, 263) to 372\n", "merged (114, 277) to 373\n", "merged (108, 256) to 374\n", "merged (97, 108) to 375\n", "merged (110, 111) to 376\n", "merged (32, 269) to 377\n", "merged (97, 109) to 378\n", "merged (353, 343) to 379\n", "merged (93, 10) to 380\n", "merged (277, 104) to 381\n", "merged (260, 98) to 382\n", "merged (10, 66) to 383\n", "merged (10, 91) to 384\n", "merged (101, 261) to 385\n", "merged (87, 104) to 386\n", "merged (100, 105) to 387\n", "merged (65, 354) to 388\n", "merged (286, 116) to 389\n", "merged (111, 112) to 390\n", "merged (106, 368) to 391\n", "merged (275, 32) to 392\n", "merged (89, 262) to 393\n", "merged (108, 265) to 394\n", "merged (309, 257) to 395\n", "merged (111, 258) to 396\n", "merged (116, 116) to 397\n", "merged (321, 121) to 398\n", "merged (315, 112) to 399\n", "merged (117, 110) to 400\n", "merged (262, 257) to 401\n", "merged (97, 121) to 402\n", "merged (73, 83) to 403\n", "merged (109, 259) to 404\n", "merged (105, 100) to 405\n", "merged (111, 103) to 406\n", "merged (105, 115) to 407\n", "merged (114, 101) to 408\n", "merged (10, 84) to 409\n", "merged (103, 104) to 410\n", "merged (97, 115) to 411\n", "merged (258, 322) to 412\n", "merged (116, 101) to 413\n", "merged (117, 114) to 414\n", "merged (331, 257) to 415\n", "merged (103, 325) to 416\n", "merged (321, 32) to 417\n", "merged (104, 256) to 418\n", "merged (73, 309) to 419\n", "merged (274, 118) to 420\n", "merged (97, 263) to 421\n", "merged (116, 111) to 422\n", "merged (271, 257) to 423\n", "merged (334, 364) to 424\n", "merged (318, 32) to 425\n", "merged (272, 110) to 426\n", "merged (259, 281) to 427\n", "merged (97, 45) to 428\n", "merged (101, 118) to 429\n", "merged (264, 256) to 430\n", "merged (97, 100) to 431\n", "merged (334, 395) to 432\n", "merged (115, 273) to 433\n", "merged (10, 76) to 434\n", "merged (260, 119) to 435\n", "merged (306, 105) to 436\n", "merged (393, 32) to 437\n", "merged (114, 256) to 438\n", "merged (105, 275) to 439\n", "merged (97, 423) to 440\n", "merged (361, 352) to 441\n", "merged (270, 32) to 442\n", "merged (262, 410) to 443\n", "merged (268, 322) to 444\n", "merged (107, 32) to 445\n", "merged (342, 32) to 446\n", "merged (111, 111) to 447\n", "merged (270, 281) to 448\n", "merged (317, 109) to 449\n", "merged (284, 267) to 450\n", "merged (10, 388) to 451\n", "merged (258, 332) to 452\n", "merged (114, 105) to 453\n", "merged (286, 257) to 454\n", "merged (406, 339) to 455\n", "merged (10, 83) to 456\n", "merged (288, 109) to 457\n", "merged (262, 394) to 458\n", "merged (108, 272) to 459\n", "merged (99, 324) to 460\n", "merged (97, 98) to 461\n", "merged (101, 109) to 462\n", "merged (361, 108) to 463\n", "merged (121, 381) to 464\n", "merged (264, 115) to 465\n", "merged (318, 281) to 466\n", "merged (121, 260) to 467\n", "merged (419, 283) to 468\n", "merged (104, 359) to 469\n", "merged (296, 103) to 470\n", "merged (116, 97) to 471\n", "merged (274, 102) to 472\n", "merged (97, 259) to 473\n", "merged (303, 300) to 474\n", "merged (278, 360) to 475\n", "merged (264, 261) to 476\n", "merged (69, 294) to 477\n", "merged (287, 260) to 478\n", "merged (101, 283) to 479\n", "merged (389, 341) to 480\n", "merged (63, 10) to 481\n", "merged (258, 365) to 482\n", "merged (104, 277) to 483\n", "merged (67, 104) to 484\n", "merged (89, 381) to 485\n", "merged (108, 263) to 486\n", "merged (58, 32) to 487\n", "merged (46, 32) to 488\n", "merged (293, 148) to 489\n", "merged (100, 260) to 490\n", "merged (97, 99) to 491\n", "merged (441, 304) to 492\n", "merged (268, 297) to 493\n", "merged (259, 32) to 494\n", "merged (336, 257) to 495\n", "merged (326, 267) to 496\n", "merged (376, 257) to 497\n", "merged (99, 97) to 498\n", "merged (107, 282) to 499\n", "merged (370, 357) to 500\n", "merged (109, 266) to 501\n", "merged (76, 455) to 502\n", "merged (287, 10) to 503\n", "merged (100, 426) to 504\n", "merged (100, 264) to 505\n", "merged (108, 101) to 506\n", "merged (86, 465) to 507\n", "merged (116, 260) to 508\n", "merged (101, 275) to 509\n", "merged (121, 372) to 510\n", "merged (110, 273) to 511\n", "merged (112, 32) to 512\n", "merged (116, 114) to 513\n", "merged (103, 105) to 514\n", "merged (344, 32) to 515\n", "merged (98, 263) to 516\n", "merged (287, 306) to 517\n", "merged (10, 71) to 518\n", "merged (258, 346) to 519\n", "merged (102, 32) to 520\n", "merged (324, 32) to 521\n", "merged (110, 292) to 522\n", "merged (260, 305) to 523\n", "merged (403, 403) to 524\n", "merged (268, 365) to 525\n", "merged (330, 299) to 526\n", "merged (384, 507) to 527\n", "merged (105, 350) to 528\n", "merged (97, 10) to 529\n", "merged (422, 281) to 530\n", "merged (116, 261) to 531\n", "merged (457, 269) to 532\n", "merged (291, 256) to 533\n", "merged (398, 372) to 534\n", "merged (39, 438) to 535\n", "merged (112, 112) to 536\n", "merged (114, 331) to 537\n", "merged (110, 417) to 538\n", "merged (397, 269) to 539\n", "merged (102, 259) to 540\n", "merged (109, 279) to 541\n", "merged (102, 327) to 542\n", "merged (285, 256) to 543\n", "merged (100, 111) to 544\n", "merged (117, 109) to 545\n", "merged (100, 273) to 546\n", "merged (104, 297) to 547\n", "merged (436, 107) to 548\n", "merged (449, 385) to 549\n", "merged (329, 282) to 550\n", "merged (356, 307) to 551\n", "merged (308, 357) to 552\n", "merged (472, 256) to 553\n", "merged (115, 97) to 554\n", "merged (116, 264) to 555\n", "merged (104, 111) to 556\n", "merged (101, 256) to 557\n", "merged (527, 256) to 558\n", "merged (269, 115) to 559\n", "merged (103, 32) to 560\n", "merged (269, 109) to 561\n", "merged (256, 310) to 562\n", "merged (99, 348) to 563\n", "merged (379, 362) to 564\n", "merged (97, 420) to 565\n", "merged (270, 284) to 566\n", "merged (336, 539) to 567\n", "merged (330, 430) to 568\n", "merged (398, 452) to 569\n", "merged (110, 97) to 570\n", "merged (73, 110) to 571\n", "merged (100, 337) to 572\n", "merged (98, 108) to 573\n", "merged (277, 360) to 574\n", "merged (119, 454) to 575\n", "merged (111, 116) to 576\n", "merged (522, 265) to 577\n", "merged (10, 72) to 578\n", "merged (97, 260) to 579\n", "merged (39, 479) to 580\n", "merged (115, 260) to 581\n", "merged (258, 297) to 582\n", "merged (119, 279) to 583\n", "merged (307, 371) to 584\n", "merged (108, 325) to 585\n", "merged (99, 266) to 586\n", "merged (286, 265) to 587\n", "merged (316, 257) to 588\n", "merged (111, 265) to 589\n", "merged (101, 108) to 590\n", "merged (119, 347) to 591\n", "merged (287, 341) to 592\n", "merged (111, 320) to 593\n", "merged (108, 121) to 594\n", "merged (115, 105) to 595\n", "merged (114, 262) to 596\n", "merged (355, 32) to 597\n", "merged (484, 279) to 598\n", "merged (598, 291) to 599\n", "merged (119, 256) to 600\n", "merged (463, 282) to 601\n", "merged (428, 548) to 602\n", "merged (109, 284) to 603\n", "merged (386, 111) to 604\n", "merged (290, 260) to 605\n", "merged (329, 32) to 606\n", "merged (316, 115) to 607\n", "merged (312, 371) to 608\n", "merged (98, 326) to 609\n", "merged (355, 377) to 610\n", "merged (104, 260) to 611\n", "merged (285, 396) to 612\n", "merged (108, 277) to 613\n", "merged (97, 103) to 614\n", "merged (111, 98) to 615\n", "merged (100, 263) to 616\n", "merged (110, 470) to 617\n", "merged (270, 256) to 618\n", "merged (115, 112) to 619\n", "merged (39, 32) to 620\n", "merged (304, 269) to 621\n", "merged (477, 510) to 622\n", "merged (99, 256) to 623\n", "merged (63, 32) to 624\n", "merged (10, 386) to 625\n", "merged (317, 270) to 626\n", "merged (10, 70) to 627\n", "merged (66, 326) to 628\n", "merged (277, 114) to 629\n", "merged (99, 363) to 630\n", "merged (10, 78) to 631\n", "merged (110, 101) to 632\n", "merged (98, 517) to 633\n", "merged (498, 533) to 634\n", "merged (487, 502) to 635\n", "merged (370, 276) to 636\n", "merged (10, 77) to 637\n", "merged (101, 390) to 638\n", "merged (105, 108) to 639\n", "merged (278, 535) to 640\n", "merged (99, 262) to 641\n", "merged (524, 260) to 642\n", "merged (480, 344) to 643\n", "merged (338, 404) to 644\n", "merged (308, 413) to 645\n", "merged (121, 10) to 646\n", "merged (363, 101) to 647\n", "merged (340, 256) to 648\n", "merged (105, 114) to 649\n", "merged (100, 114) to 650\n", "merged (114, 415) to 651\n", "merged (262, 369) to 652\n", "merged (429, 299) to 653\n", "merged (104, 32) to 654\n", "merged (542, 283) to 655\n", "merged (329, 476) to 656\n", "merged (313, 32) to 657\n", "merged (262, 354) to 658\n", "merged (111, 294) to 659\n", "merged (355, 281) to 660\n", "merged (103, 273) to 661\n", "merged (107, 284) to 662\n", "merged (268, 346) to 663\n", "merged (107, 439) to 664\n", "merged (107, 105) to 665\n", "merged (373, 306) to 666\n", "merged (604, 97) to 667\n", "merged (320, 416) to 668\n", "merged (115, 647) to 669\n", "merged (109, 335) to 670\n", "merged (309, 261) to 671\n", "merged (104, 363) to 672\n", "merged (258, 290) to 673\n", "merged (513, 121) to 674\n", "merged (286, 114) to 675\n", "merged (116, 327) to 676\n", "merged (259, 345) to 677\n", "merged (382, 326) to 678\n", "merged (435, 256) to 679\n", "merged (344, 260) to 680\n", "merged (399, 32) to 681\n", "merged (111, 107) to 682\n", "merged (10, 393) to 683\n", "merged (100, 101) to 684\n", "merged (596, 110) to 685\n", "merged (519, 341) to 686\n", "merged (384, 599) to 687\n", "merged (118, 105) to 688\n", "merged (303, 287) to 689\n", "merged (10, 79) to 690\n", "merged (317, 320) to 691\n", "merged (40, 66) to 692\n", "merged (102, 491) to 693\n", "merged (98, 277) to 694\n", "merged (40, 87) to 695\n", "merged (303, 458) to 696\n", "merged (71, 311) to 697\n", "merged (40, 667) to 698\n", "merged (447, 33) to 699\n", "merged (668, 644) to 700\n", "merged (342, 345) to 701\n", "merged (73, 257) to 702\n", "merged (473, 395) to 703\n", "merged (10, 65) to 704\n", "merged (396, 337) to 705\n", "merged (112, 308) to 706\n", "merged (10, 437) to 707\n", "merged (324, 263) to 708\n", "merged (330, 273) to 709\n", "merged (514, 307) to 710\n", "merged (41, 312) to 711\n", "merged (118, 282) to 712\n", "merged (304, 258) to 713\n", "merged (119, 270) to 714\n", "merged (116, 282) to 715\n", "merged (110, 32) to 716\n", "merged (518, 325) to 717\n", "merged (276, 101) to 718\n", "merged (108, 359) to 719\n", "merged (119, 421) to 720\n", "merged (119, 402) to 721\n", "merged (270, 345) to 722\n", "merged (39, 634) to 723\n", "merged (635, 380) to 724\n", "merged (602, 602) to 725\n", "merged (383, 326) to 726\n", "merged (103, 270) to 727\n", "merged (111, 121) to 728\n", "merged (316, 256) to 729\n", "merged (112, 638) to 730\n", "merged (99, 458) to 731\n", "merged (351, 301) to 732\n", "merged (308, 276) to 733\n", "merged (270, 486) to 734\n", "merged (308, 307) to 735\n", "merged (698, 328) to 736\n", "merged (399, 382) to 737\n", "merged (109, 348) to 738\n", "merged (379, 387) to 739\n", "merged (270, 101) to 740\n", "merged (461, 401) to 741\n", "merged (274, 410) to 742\n", "merged (258, 264) to 743\n", "merged (108, 100) to 744\n", "merged (108, 270) to 745\n", "merged (674, 343) to 746\n", "merged (266, 121) to 747\n", "merged (526, 267) to 748\n", "merged (264, 656) to 749\n", "merged (340, 658) to 750\n", "merged (434, 105) to 751\n", "merged (302, 390) to 752\n", "merged (681, 303) to 753\n", "merged (66, 327) to 754\n", "merged (317, 718) to 755\n", "merged (755, 531) to 756\n", "merged (52, 48) to 757\n", "merged (375, 433) to 758\n", "merged (274, 662) to 759\n", "merged (105, 109) to 760\n", "merged (615, 516) to 761\n", "merged (97, 289) to 762\n", "merged (464, 260) to 763\n", "merged (104, 300) to 764\n", "merged (111, 394) to 765\n", "merged (101, 392) to 766\n", "merged (295, 32) to 767\n", "merged (10, 485) to 768\n", "merged (296, 32) to 769\n", "merged (107, 292) to 770\n", "merged (271, 260) to 771\n", "merged (267, 109) to 772\n", "merged (483, 114) to 773\n", "merged (266, 100) to 774\n", "merged (356, 118) to 775\n", "merged (97, 329) to 776\n", "merged (114, 605) to 777\n", "merged (286, 109) to 778\n", "merged (10, 87) to 779\n", "merged (303, 32) to 780\n", "merged (549, 466) to 781\n", "merged (642, 642) to 782\n", "merged (260, 338) to 783\n", "merged (434, 325) to 784\n", "merged (492, 338) to 785\n", "merged (107, 259) to 786\n", "merged (258, 259) to 787\n", "merged (104, 264) to 788\n", "merged (409, 104) to 789\n", "merged (115, 257) to 790\n", "merged (256, 40) to 791\n", "merged (267, 115) to 792\n", "merged (384, 571) to 793\n", "merged (713, 528) to 794\n", "merged (287, 256) to 795\n", "merged (612, 749) to 796\n", "merged (101, 100) to 797\n", "merged (271, 268) to 798\n", "merged (114, 443) to 799\n", "merged (108, 117) to 800\n", "merged (102, 117) to 801\n", "merged (100, 378) to 802\n", "merged (557, 753) to 803\n", "merged (803, 272) to 804\n", "merged (804, 261) to 805\n", "merged (805, 110) to 806\n", "merged (806, 574) to 807\n", "merged (807, 754) to 808\n", "merged (808, 682) to 809\n", "merged (809, 594) to 810\n", "merged (810, 110) to 811\n", "merged (811, 717) to 812\n", "merged (812, 756) to 813\n", "merged (813, 347) to 814\n", "merged (814, 719) to 815\n", "merged (815, 347) to 816\n", "merged (816, 36) to 817\n", "merged (817, 757) to 818\n", "merged (818, 683) to 819\n", "merged (819, 285) to 820\n", "merged (820, 415) to 821\n", "merged (821, 758) to 822\n", "merged (822, 759) to 823\n", "merged (306, 266) to 824\n", "merged (382, 496) to 825\n", "merged (471, 289) to 826\n", "merged (114, 292) to 827\n", "merged (99, 315) to 828\n", "merged (101, 397) to 829\n", "merged (301, 98) to 830\n", "merged (112, 114) to 831\n", "merged (586, 364) to 832\n", "merged (105, 107) to 833\n", "merged (117, 99) to 834\n", "merged (259, 377) to 835\n", "merged (406, 32) to 836\n", "merged (302, 105) to 837\n", "merged (288, 584) to 838\n", "merged (777, 777) to 839\n", "merged (10, 622) to 840\n", "merged (695, 699) to 841\n", "merged (121, 349) to 842\n", "merged (537, 369) to 843\n", "merged (562, 541) to 844\n", "merged (339, 576) to 845\n", "merged (845, 259) to 846\n", "merged (297, 375) to 847\n", "merged (358, 702) to 848\n", "merged (785, 553) to 849\n", "merged (565, 450) to 850\n", "merged (429, 280) to 851\n", "merged (312, 366) to 852\n", "merged (278, 114) to 853\n", "merged (353, 257) to 854\n", "merged (284, 78) to 855\n", "merged (400, 505) to 856\n", "merged (331, 116) to 857\n", "merged (383, 496) to 858\n", "merged (76, 105) to 859\n", "merged (119, 114) to 860\n", "merged (356, 111) to 861\n", "merged (100, 402) to 862\n", "merged (70, 657) to 863\n", "merged (672, 105) to 864\n", "merged (99, 593) to 865\n", "merged (105, 374) to 866\n", "merged (316, 260) to 867\n", "merged (310, 314) to 868\n", "merged (111, 257) to 869\n", "merged (97, 102) to 870\n", "merged (116, 588) to 871\n", "merged (389, 256) to 872\n", "merged (114, 400) to 873\n", "merged (279, 32) to 874\n", "merged (420, 282) to 875\n", "merged (39, 462) to 876\n", "merged (102, 378) to 877\n", "merged (67, 97) to 878\n", "merged (402, 362) to 879\n", "merged (101, 341) to 880\n", "merged (115, 109) to 881\n", "merged (110, 364) to 882\n", "merged (98, 111) to 883\n", "merged (65, 121) to 884\n", "merged (100, 103) to 885\n", "merged (80, 666) to 886\n", "merged (286, 307) to 887\n", "merged (112, 105) to 888\n", "merged (469, 301) to 889\n", "merged (335, 534) to 890\n", "merged (841, 328) to 891\n", "merged (836, 39) to 892\n", "merged (892, 685) to 893\n", "merged (893, 100) to 894\n", "merged (894, 489) to 895\n", "merged (655, 97) to 896\n", "merged (896, 489) to 897\n", "merged (74, 316) to 898\n", "merged (595, 302) to 899\n", "merged (115, 270) to 900\n", "merged (569, 847) to 901\n", "merged (419, 584) to 902\n", "merged (107, 290) to 903\n", "merged (492, 468) to 904\n", "merged (401, 701) to 905\n", "merged (404, 284) to 906\n", "merged (116, 375) to 907\n", "merged (112, 315) to 908\n", "merged (303, 359) to 909\n", "merged (376, 372) to 910\n", "merged (789, 365) to 911\n", "merged (115, 421) to 912\n", "merged (298, 301) to 913\n", "merged (625, 299) to 914\n", "merged (316, 261) to 915\n", "merged (71, 589) to 916\n", "merged (568, 298) to 917\n", "merged (274, 397) to 918\n", "merged (918, 374) to 919\n", "merged (540, 708) to 920\n", "merged (676, 380) to 921\n", "merged (10, 558) to 922\n", "merged (370, 98) to 923\n", "merged (427, 99) to 924\n", "merged (331, 369) to 925\n", "merged (802, 110) to 926\n", "merged (301, 109) to 927\n", "merged (116, 390) to 928\n", "merged (115, 593) to 929\n", "merged (83, 823) to 930\n", "merged (632, 119) to 931\n", "merged (98, 356) to 932\n", "merged (109, 396) to 933\n", "merged (269, 98) to 934\n", "merged (268, 443) to 935\n", "merged (114, 405) to 936\n", "merged (101, 99) to 937\n", "merged (280, 265) to 938\n", "merged (117, 116) to 939\n", "merged (334, 256) to 940\n", "merged (630, 282) to 941\n", "merged (303, 503) to 942\n", "merged (493, 474) to 943\n", "merged (84, 104) to 944\n", "merged (115, 256) to 945\n", "merged (304, 314) to 946\n", "merged (114, 272) to 947\n", "merged (730, 374) to 948\n", "merged (109, 281) to 949\n", "merged (516, 314) to 950\n", "merged (10, 305) to 951\n", "merged (112, 291) to 952\n", "merged (271, 281) to 953\n", "merged (614, 473) to 954\n", "merged (297, 314) to 955\n", "merged (346, 116) to 956\n", "merged (10, 68) to 957\n", "merged (336, 282) to 958\n", "merged (884, 121) to 959\n", "merged (349, 371) to 960\n", "merged (121, 111) to 961\n", "merged (961, 620) to 962\n", "merged (83, 112) to 963\n", "merged (97, 302) to 964\n", "merged (116, 351) to 965\n", "merged (407, 105) to 966\n", "merged (573, 292) to 967\n", "merged (112, 264) to 968\n", "merged (318, 268) to 969\n", "merged (85, 611) to 970\n", "merged (100, 97) to 971\n", "merged (844, 844) to 972\n", "merged (83, 101) to 973\n", "merged (902, 448) to 974\n", "merged (974, 459) to 975\n", "merged (608, 471) to 976\n", "merged (976, 903) to 977\n", "merged (977, 345) to 978\n", "merged (978, 449) to 979\n", "merged (979, 450) to 980\n", "merged (980, 904) to 981\n", "merged (981, 905) to 982\n", "merged (982, 404) to 983\n", "merged (983, 848) to 984\n", "merged (984, 849) to 985\n", "merged (985, 703) to 986\n", "merged (986, 906) to 987\n", "merged (116, 311) to 988\n", "merged (413, 392) to 989\n", "merged (98, 401) to 990\n", "merged (787, 107) to 991\n", "merged (112, 104) to 992\n", "merged (853, 285) to 993\n", "merged (99, 105) to 994\n", "merged (565, 284) to 995\n", "merged (10, 73) to 996\n", "merged (102, 649) to 997\n", "merged (98, 373) to 998\n", "merged (275, 268) to 999\n", "merged (100, 421) to 1000\n", "merged (651, 295) to 1001\n", "merged (920, 564) to 1002\n", "merged (409, 418) to 1003\n", "merged (111, 118) to 1004\n", "merged (103, 261) to 1005\n", "merged (114, 263) to 1006\n", "merged (336, 589) to 1007\n", "merged (260, 298) to 1008\n", "merged (112, 327) to 1009\n", "merged (363, 109) to 1010\n", "merged (413, 275) to 1011\n", "merged (275, 263) to 1012\n", "merged (98, 105) to 1013\n", "merged (281, 110) to 1014\n", "merged (99, 340) to 1015\n", "merged (256, 298) to 1016\n", "merged (613, 307) to 1017\n", "merged (111, 260) to 1018\n", "merged (376, 260) to 1019\n", "merged (266, 705) to 1020\n", "merged (121, 629) to 1021\n", "merged (105, 258) to 1022\n", "merged (66, 761) to 1023\n", "[975, 10, 987, 386, 273, 563, 408, 645, 481, 975, 987, 312, 432, 564, 850, 432, 564, 850, 391, 739, 256, 988, 402, 312, 391, 739, 450, 432, 564, 850, 432, 564, 850, 391, 739, 284, 388, 585, 320, 989, 298, 330, 646, 704, 275, 493, 705, 474, 468, 907]\n" ] } ], "source": [ "with open(\"logic_lyrics.txt\", \"r\") as f:\n", " text = f.read()\n", "\n", "print(text[:50])\n", "\n", "new_text = list(text.encode('utf-8'))\n", "\n", "print(new_text[:50])\n", "\n", "text = text.encode('utf-8')\n", "\n", "\n", "old_vocab_size = 256 # utf-8 has 256 characters\n", "new_vocab_size = 1024 # arbitrary number to increase vocab to\n", "\n", "num_merges = new_vocab_size - old_vocab_size\n", "\n", "merge = {}\n", "\n", "for i in range(num_merges):\n", " counts = get_counts(new_text)\n", " top_pair = max(counts, key=counts.get)\n", " merge[top_pair] = i + old_vocab_size\n", " new_text = merge_token(top_pair, new_text, i + old_vocab_size)\n", " print(f\"merged {top_pair} to {i + old_vocab_size}\")\n", "\n", "\n", "print(new_text[:50])\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "original length: 43508\n", "tokens length: 14469\n", "compression ratio: 0.33255952928197113\n", "[975, 10, 987, 386, 273, 563, 408, 645, 481, 975, 987, 312, 432, 564, 850, 432, 564, 850, 391, 739, 256, 988, 402, 312, 391, 739, 450, 432, 564, 850, 432, 564, 850, 391, 739, 284, 388, 585, 320, 989, 298, 330, 646, 704, 275, 493, 705, 474, 468, 907]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Vocab size: 256, Compression Ratio: 1.0\n", "Vocab size: 288, Compression Ratio: 0.7335432564126138\n", "Vocab size: 320, Compression Ratio: 0.6502252459317827\n", "Vocab size: 352, Compression Ratio: 0.5953617725475775\n", "Vocab size: 384, Compression Ratio: 0.5540590236278385\n", "Vocab size: 416, Compression Ratio: 0.5220419233244461\n", "Vocab size: 448, Compression Ratio: 0.49868989611106\n", "Vocab size: 480, Compression Ratio: 0.4790613220557139\n", "Vocab size: 512, Compression Ratio: 0.46207594005700103\n", "Vocab size: 544, Compression Ratio: 0.4472051117035947\n", "Vocab size: 576, Compression Ratio: 0.43405810425668845\n", "Vocab size: 608, Compression Ratio: 0.4221062793049554\n", "Vocab size: 640, Compression Ratio: 0.4114645582421624\n", "Vocab size: 672, Compression Ratio: 0.40185712972326926\n", "Vocab size: 704, Compression Ratio: 0.3931001195182495\n", "Vocab size: 736, Compression Ratio: 0.38510159051208975\n", "Vocab size: 768, Compression Ratio: 0.37767766847476325\n", "Vocab size: 800, Compression Ratio: 0.37073641629125675\n", "Vocab size: 832, Compression Ratio: 0.364116944010297\n", "Vocab size: 864, Compression Ratio: 0.3579571573044038\n", "Vocab size: 896, Compression Ratio: 0.3520731819435506\n", "Vocab size: 928, Compression Ratio: 0.3467867978302841\n", "Vocab size: 960, Compression Ratio: 0.34163831938953754\n", "Vocab size: 992, Compression Ratio: 0.33697251080261104\n", "Vocab size: 1024, Compression Ratio: 0.33255952928197113\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAIhCAYAAAB5deq6AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACLm0lEQVR4nOzdd3hUdfr+8Xsy6RWSkEpIQqghgnQBXVQEQcQu2BApq4iCyKorolLWn6jrl8UG2FHR1bWL0qIiolTpvQZCSSGFJBDSz++PmJGQhCQwmZkk79d15YI5c87MMw9Bc3M+5zkmwzAMAQAAAACq5GTvAgAAAADA0RGcAAAAAKAaBCcAAAAAqAbBCQAAAACqQXACAAAAgGoQnAAAAACgGgQnAAAAAKgGwQkAAAAAqkFwAgAAAIBqEJwA2N3WrVs1cuRIRUdHy93dXd7e3urSpYteeuklZWRk2Lu8emHatGkymUx2ee+oqCiZTCbLl5eXl7p06aLXX39dhmFc0GuuWrVK06ZN08mTJys8d+WVV+rKK6+8uKLtqHPnzgoPD1dxcXGV+/Tp00eBgYEqKCiwYWV/MZlMevjhh636mo7451ZYWKg333xT3bt3l7+/vzw9PRUZGakbb7xRX3/9tWW/Q4cOyWQyaf78+fYrFoDdEZwA2NXbb7+trl27av369Xr88ce1ZMkSff3117r99ts1b948jR492t4l1gtjxozR6tWr7fb+ffr00erVq7V69Wp99NFH8vT01Pjx4zVz5swLer1Vq1Zp+vTplQanOXPmaM6cORdZsf2MHj1ax48f19KlSyt9fu/evVq1apWGDx8uV1dXG1fXuAwfPlzjx4/XVVddpQULFmjhwoV6+umn5ezsXO7PJzQ0VKtXr9bgwYPtWC0AezMZF/rPgQBwkVavXq0rrrhC/fv31zfffCM3N7dyzxcUFGjJkiW64YYb7FThhTlz5ow8PDzsXYbNREVFKS4uTt9//71lW3Z2tlq0aCE/Pz8dPny41q/58ssv6/HHH1dCQoKioqKsWK39ZWZmKiwsTIMHD9YXX3xR4fknn3xSL774orZu3apLLrnEDhWWnnF66KGH9Prrr1vtNcvONv3yyy9Web2L/XuWkJCgli1b6tlnn9X06dMrPF9SUiInJ/59GcBf+C8CALt5/vnnZTKZ9NZbb1UITZLk6upaLjSVlJTopZdeUrt27eTm5qagoCDde++9Onr0aLnjrrzySsXFxWn16tXq3bu3PDw8FBUVpffff1+S9MMPP6hLly7y9PTUJZdcoiVLlpQ7vmzZ26ZNm3TLLbfI19dXfn5+uueee3TixIly+0ZFRen666/XV199pc6dO8vd3d3yQ1hycrIeeOABNW/eXK6uroqOjtb06dNVVFRU7jXmzp2rTp06ydvbWz4+PmrXrp2eeuopy/O5ubl67LHHLEsZ/f391a1bN/33v/+tUPPZatuv9evX64orrpCnp6datmypF154QSUlJZX/4VXD19dXbdq0UUpKSrnt8fHxuvHGG9W8eXO5u7urVatWeuCBB5SWllbuszz++OOSpOjoaMsSwLIfuCtb8pWRkaFx48YpPDxcrq6uatmypaZMmaL8/Pzz1jlx4kR5eXkpOzu7wnPDhg1TcHCwCgsLJUk///yzrrzySgUEBMjDw0MtWrTQrbfeqtzc3Fr1pmnTprr55pu1cOFCpaenl3uuuLhYH330kbp3724JTb/99pv69esnHx8feXp6qnfv3vrhhx8qvO6xY8d0//33KyIiQq6urgoLC9Ntt91m+TPIy8vTP/7xD1166aXy8/OTv7+/evXqpW+//bbKWt988021adNGbm5uio2N1aefflru+aqWiM6fP18mk0mHDh06by+mT5+unj17yt/fX76+vurSpYvefffdCks8q/p71q9fP7Vr167C/oZhqFWrVuc9Q1TW+9DQ0EqfPzs0VbZU7+zlqed+nf25//jjD91www3y9/eXu7u7OnfurP/973/n7QsAx+Rs7wIANE7FxcX6+eef1bVrV0VERNTomAcffFBvvfWWHn74YV1//fU6dOiQnnnmGf3yyy/auHGjAgMDLfsmJydr5MiReuKJJ9S8eXO99tprGjVqlI4cOaIvvvhCTz31lPz8/DRjxgzddNNNOnjwoMLCwsq9380336yhQ4dq7Nix2rFjh5555hnt3LlTa9eulYuLi2W/jRs3ateuXXr66acVHR0tLy8vJScnq0ePHnJyctKzzz6rmJgYrV69Ws8995wOHTpkCXGffvqpxo0bp/Hjx+vll1+Wk5OT9u/fr507d1pef9KkSfroo4/03HPPqXPnzjp9+rS2b99e4Yfui+3X3XffrX/84x+aOnWqvv76a02ePFlhYWG69957a/Tnc7aioiIdOXJEbdq0Kbf9wIED6tWrl8aMGSM/Pz8dOnRIs2bN0uWXX65t27bJxcVFY8aMUUZGhl577TV99dVXlh9sY2NjK32vvLw8XXXVVTpw4ICmT5+ujh07auXKlZo5c6Y2b95cacgoM2rUKL3yyiv63//+pzFjxli2nzx5Ut9++60eeughubi46NChQxo8eLCuuOIKvffee2rSpImOHTumJUuWqKCgQJ6enrXqz+jRo/Xf//5XCxYs0COPPGLZvnTpUh0/flzPPvusJGnFihXq37+/OnbsqHfffVdubm6aM2eOhgwZov/+978aNmyYpNLQ1L17dxUWFuqpp55Sx44dlZ6erqVLlyozM1PBwcHKz89XRkaGHnvsMYWHh6ugoEA//vijbrnlFr3//vsV/py/++47LV++XDNmzJCXl5fmzJmjO++8U87Ozrrttttq9XmrcujQIT3wwANq0aKFJGnNmjUaP368jh07ZulBmcr+nvXu3Vs33nijfvrpJ11zzTWWfRcvXqwDBw7o1VdfrfK927dvryZNmmj69OlycnLSgAEDanV289ylsWfOnNHw4cNVXFwsf39/SdLy5cs1cOBA9ezZU/PmzZOfn58+/fRTDRs2TLm5ubrvvvtq/H4AHIABAHaQnJxsSDLuuOOOGu2/a9cuQ5Ixbty4ctvXrl1rSDKeeuopy7a+ffsakow//vjDsi09Pd0wm82Gh4eHcezYMcv2zZs3G5KMV1991bJt6tSphiTj0UcfLfdeH3/8sSHJWLBggWVbZGSkYTabjT179pTb94EHHjC8vb2Nw4cPl9v+8ssvG5KMHTt2GIZhGA8//LDRpEmT8372uLg446abbjrvPmU1l7mQfq1du7bcvrGxsca111573vc1jNIeXHfddUZhYaFRWFhoHD582Pj73/9uuLi4GN9//32Vx5WUlFj2l2R8++23luf+/e9/G5KMhISECsf17dvX6Nu3r+XxvHnzDEnG//73v3L7vfjii4YkY9myZeetv0uXLkbv3r3LbZszZ44hydi2bZthGIbxxRdfGJKMzZs3n/e1aqqkpMSIjo42OnbsWG77rbfeanh6ehpZWVmGYRjGZZddZgQFBRk5OTmWfYqKioy4uDijefPmRklJiWEYhjFq1CjDxcXF2LlzZ41rKCoqMgoLC43Ro0cbnTt3LvecJMPDw8NITk4ut3+7du2MVq1aWbad+31X5v3336/w53fun9u5iouLjcLCQmPGjBlGQECA5bMZRtV/z4qLi42WLVsaN954Y7ntgwYNMmJiYsq9RmV++OEHIzAw0JBkSDICAgKM22+/3fjuu+/K7ZeQkGBIMt5///1KX6eoqMi48cYbDW9vb2PDhg2W7e3atTM6d+5sFBYWltv/+uuvN0JDQ43i4uLz1gfAsbBUD0C9sHz5ckmq8C+0PXr0UPv27fXTTz+V2x4aGqquXbtaHvv7+ysoKEiXXnppuTNL7du3l6RKr8O5++67yz0eOnSonJ2dLbWU6dixY4UzK99//72uuuoqhYWFqaioyPI1aNAgSaVnEsrqP3nypO688059++235Zasnf0ZFy9erCeffFK//PKLzpw5U7FB56htv0JCQtSjR48Kn6um1yctWrRILi4ucnFxUWRkpN5++2299tprFZZKpaamauzYsYqIiJCzs7Nlf0natWtXjd7rXD///LO8vLwqnAUp++znftZzjRw5UqtWrdKePXss295//311795dcXFxkqRLL71Urq6uuv/++/XBBx/o4MGDF1RrGZPJpJEjR2rr1q3asGGDpNKlYwsXLtStt94qX19fnT59WmvXrtVtt90mb29vy7Fms1nDhw/X0aNHLTUvXrxYV111leX7uSqff/65+vTpI29vb0v/33333Up7369fPwUHB5d732HDhmn//v0VlnteqJ9//lnXXHON/Pz8ZDab5eLiomeffVbp6elKTU0tt29lf8+cnJz08MMP6/vvv1diYqKk0rOaS5Ys0bhx46qdNHndddcpMTFRX3/9tR577DF16NBB33zzjW644YZaTRV8+OGH9cMPP+jzzz9Xly5dJEn79+/X7t27Lf8dOfu/A9ddd52SkpLKfc8BcHwEJwB2ERgYKE9PTyUkJNRo//NdjxAWFlZh2VrZUpmzubq6VtheNrUsLy+vwv4hISHlHjs7OysgIKDCe1VWU0pKihYuXGgJE2VfHTp0kCRLQBo+fLjee+89HT58WLfeequCgoLUs2dPxcfHW17r1Vdf1T//+U998803uuqqq+Tv76+bbrpJ+/btq/C+ZWrbr4CAgAr7ubm51SikSdLll1+u9evXa82aNfroo48UFRWlhx9+WL/99ptln5KSEg0YMEBfffWVnnjiCf30009at26d1qxZI0k1fq9zpaenKyQkpMIPyUFBQXJ2dq52SePdd98tNzc3y/UrO3fu1Pr16zVy5EjLPjExMfrxxx8VFBSkhx56SDExMYqJidErr7xyQTVLpYHNycnJsmzz448/VkFBgWWSZGZmpgzDqPLPsOyzS9KJEyfUvHnz877fV199paFDhyo8PFwLFizQ6tWrtX79eo0aNapG3/9nb6uupzWxbt06DRgwQFLpdM3ff/9d69ev15QpUyRV/H6o6lqkUaNGycPDQ/PmzZMkvfHGG/Lw8NCoUaNqVIeHh4duuukm/fvf/9aKFSu0f/9+xcbG6o033tCOHTuqPf65557TvHnz9Oabb2rgwIGW7WXXlj322GMV/jswbtw4Sar0H0oAOC6CEwC7MJvN6tevnzZs2FCjf70u+8E+KSmpwnPHjx8vd72OtSQnJ5d7XFRUpPT09Aoho7J/1Q4MDNSAAQO0fv36Sr/OHrNedsYjKytLP/zwgwzD0PXXX2852+Pl5aXp06dr9+7dSk5O1ty5c7VmzRoNGTKkytpt3S8/Pz9169ZNPXv21D333KNly5ZZfkAsGzCxfft2bdmyRf/+9781fvx4XXnllerevXuloa02AgIClJKSUmFAQGpqqoqKiqr9rE2bNtWNN96oDz/8UMXFxXr//ffl7u6uO++8s9x+V1xxhRYuXKisrCytWbNGvXr10sSJEysMTKip5s2ba8CAAfrkk0+Un5+v999/X61atdLf/vY3S11OTk5V/hlKsny2Zs2aVfv3aMGCBYqOjtZnn32mm266SZdddpm6detW5QCNc7//z95W9mfm7u4uSRVeoyaB4NNPP5WLi4u+//57DR06VL1791a3bt2q3L+qs0d+fn4aMWKE3nnnHWVkZOj999/XXXfdpSZNmlRbQ2VatGih+++/X5KqDU7z58/XM888o2nTplUIamV/NpMnT67yvwOXXnrpBdUIwD4ITgDsZvLkyTIMQ3//+98rvdFnYWGhFi5cKEm6+uqrJZX+8He29evXa9euXerXr5/V6/v444/LPf7f//6noqKiGt3E8/rrr9f27dsVExOjbt26Vfg6dxCFVBqQBg0apClTpqigoKDSH9qCg4N133336c4779SePXuqnOhmj36drXXr1nriiSe0bds2ffbZZ5L++sH33AmKb775ZoXjy/apyVmofv366dSpU/rmm2/Kbf/www8tz1dn5MiROn78uBYtWqQFCxbo5ptvrvIHb7PZrJ49e+qNN96QVDq04EKNHj1amZmZevbZZ7V582aNHDnS0icvLy/17NlTX331Vbk+lJSUaMGCBWrevLll6dqgQYO0fPny8y79MplMcnV1LRdAkpOTq5yq99NPP5WbilhcXKzPPvtMMTExlrNbZcMUtm7dWu7Ysr+352MymeTs7Cyz2WzZdubMGX300UfVHnuuCRMmKC0tTbfddptOnjxZo2V2OTk5OnXqVKXPlS1drOzvaZklS5bo73//u0aNGqWpU6dWeL5t27Zq3bq1tmzZUul/A7p16yYfH58afkIAjoCpegDsplevXpo7d67GjRunrl276sEHH1SHDh1UWFioTZs26a233lJcXJyGDBmitm3b6v7779drr70mJycnDRo0yDIlLiIiQo8++qjV6/vqq6/k7Oys/v37W6bqderUSUOHDq322BkzZig+Pl69e/fWhAkT1LZtW+Xl5enQoUNatGiR5s2bp+bNm+vvf/+7PDw81KdPH4WGhio5OVkzZ86Un5+funfvLknq2bOnrr/+enXs2FFNmzbVrl279NFHH6lXr15VTnOzR7/O9dhjj2nevHmaPn26hg4dqnbt2ikmJkZPPvmkDMOQv7+/Fi5cWG5ZYpmyUdyvvPKKRowYIRcXF7Vt27bSHzTvvfdevfHGGxoxYoQOHTqkSy65RL/99puef/55XXfddeWmrVVlwIABat68ucaNG2eZyHi2efPm6eeff9bgwYPVokUL5eXl6b333pOkcq/fqlUrSaXXt9TEDTfcoMDAQP373/+W2WzWiBEjyj0/c+ZM9e/fX1dddZUee+wxubq6as6cOdq+fbv++9//WkLQjBkztHjxYv3tb3/TU089pUsuuUQnT57UkiVLNGnSJLVr184yznvcuHG67bbbdOTIEf3rX/9SaGhopcs+AwMDdfXVV+uZZ56xTNXbvXt3uTNs1113nfz9/TV69GjNmDFDzs7Omj9/vo4cOVLtZx88eLBmzZqlu+66S/fff7/S09P18ssvV3prguq0adNGAwcO1OLFi3X55ZerU6dO1R6zZ88eXXvttbrjjjvUt29fhYaGKjMzUz/88IPeeustXXnllerdu3elxyYkJOj2229Xy5YtNXLkSMty0zKdO3eWm5ub3nzzTQ0aNEjXXnut7rvvPoWH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77Dr4uKikpISqxQF2IKbs1mzh12qB/q2lCS9vGyvpnyzXUXFfB8DAACgvFoHp6uvvlqPPPKIjh8/btl27NgxPfroo+rXr59ViwPqmpOTSZMHtdf0GzrIZJI+WZuosQs2KLegyN6lAQAAwIHUOji9/vrrysnJUVRUlGJiYtSqVStFR0crJydHr732Wl3UCNS5Eb2jNPfurnJzdtKPu1J159trlXYq395lAQAAwEHUeqpeRESENm7cqPj4eO3evVuGYSg2NlbXXHNNXdQH2MzAuBB98veeGv3BH9py5KRunbtKH4zsoahAL3uXBgAAADu74Ps49e/fX/3797dmLYDddY3015cP9taI99bpcHqubp27Su/e112XRjSxd2kAAACwoxov1fv5558VGxur7OzsCs9lZWWpQ4cOWrlypVWLA+whppm3vhrXW3Hhvko/XaA73lqtn3al2LssAAAA2FGNg9Ps2bP197//Xb6+vhWe8/Pz0wMPPKBZs2ZZtTjAXoJ83PXp/b30tzbNlFdYor9/+Ic+WZto77IAAABgJzUOTlu2bNHAgQOrfH7AgAHasGGDVYoCHIG3m7PeHdFNt3dtrhJDeurrbfq/ZXu41xMAAEAjVOPglJKSUun9m8o4OzvrxIkTVikKcBQuZie9dFtHTejXWpL02s/79djnW1XIvZ4AAAAalRoHp/DwcG3btq3K57du3arQ0FCrFAU4EpPJpEn922jmLZfI7GTSlxuPatT89TqVz72eAAAAGosaB6frrrtOzz77rPLy8io8d+bMGU2dOlXXX3+9VYsDHMmdPVro7Xu7ysPFrJX70jR03mqlZlf8+wAAAICGp8bB6emnn1ZGRobatGmjl156Sd9++62+++47vfjii2rbtq0yMjI0ZcqUuqwVsLur2wXr0/svU4CXq3YmZevmOau0PzXH3mUBAACgjtX4Pk7BwcFatWqVHnzwQU2ePNlygbzJZNK1116rOXPmKDg4uM4KBRxFp4gm+mpcb933/nolpJ3WrXNX650R3dQ9yl/FJYbWJWQoNSdPQT7u6hHtL7OTyd4lAwAA4CLV6ga4kZGRWrRokTIzM7V//34ZhqHWrVuradOmdVUf4JAiA7z0xdheGv3BH9p85KTufmet7usVqYVbk5SU9dfyvVA/d00dEquBcVz/BwAAUJ/VeKne2Zo2baru3burR48e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ZCxfvtwwDHptTc8995wREBBgfP/990ZCQoLx+eefG97e3sbs2bMt+9Bv6xo6dKgRGxtrrFixwti3b58xdepUw9fX1zh69KhhGPT7YixatMiYMmWK8eWXXxqSjK+//rrc89bq7cCBA424uDhj1apVxqpVq4y4uDjj+uuvt9XHtAmCEwzDMIymTZsa77zzjlFSUmKEhIQYL7zwguW5vLw8w8/Pz5g3b55hGIZx8uRJw8XFxfj0008t+xw7dsxwcnIylixZYvPa64OcnByjdevWRnx8vNG3b19LcKLf1jV16lSjU6dOlT5Hr63vn//8p3H55ZdX+Tw9r1uPPPKIERMTY5SUlNBrKxs8eLAxatSocttuueUW45577jEMg+9ta8vNzTXMZrPx/fffl9veqVMnY8qUKfTbis4NTtbq7c6dOw1Jxpo1ayz7rF692pBk7N69u44/le2wVK+RKy4u1qeffqrTp0+rV69eSkhIUHJysgYMGGDZx83NTX379tWqVaskSRs2bFBhYWG5fcLCwhQXF2fZB+U99NBDGjx4sK655ppy2+m39e3bt09hYWGKjo7WHXfcoYMHD0qi13Xhu+++U7du3XT77bcrKChInTt31ttvv215np7XnYKCAi1YsECjRo2SyWSi11Z2+eWX66efftLevXslSVu2bNFvv/2m6667ThLf29ZWVFSk4uJiubu7l9vu4eGh3377jX7XIWv1dvXq1fLz81PPnj0t+1x22WXy8/NrUP0nODVS27Ztk7e3t9zc3DR27Fh9/fXXio2NVXJysiQpODi43P7BwcGW55KTk+Xq6qqmTZtWuQ/+8umnn2rjxo2aOXNmhefot3X17NlTH374oZYuXaq3335bycnJ6t27t9LT0+l1HTh48KDmzp2r1q1ba+nSpRo7dqwmTJigDz/8UBLf33Xpm2++0cmTJ3XfffdJotfW9s9//lN33nmn2rVrJxcXF3Xu3FkTJ07UnXfeKYl+W5uPj4969eqlf/3rXzp+/LiKi4u1YMECrV27VklJSfS7Dlmrt8nJyQoKCqrw+kFBQQ2q/872LgD20bZtW23evFknT57Ul19+qREjRmjFihWW500mU7n9DcOosO1cNdmnsTly5IgeeeQRLVu2rMK/pJ2NflvHoEGDLL+/5JJL1KtXL8XExOiDDz7QZZddJoleW1NJSYm6deum559/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enPx4kV6e3vHnNNHH32ExWJh165d7jZvpweO5bHHHqOkpIT+/n4SEhKYP3/+hN8FmD17NuHh4Vy+fNnr8+7ubtLS0igoKCA1NdXjWVxcHIcOHXIflCEiIteXVpxERGRCDMMgIyODgoICvvvuO4/Vlaeffppjx47x4osv0tXVRU1NDa+++irPPPMM8OfpcNnZ2eTm5tLQ0EBvby8nTpxwH/6waNEiPvnkE44cOUJXVxd2u50zZ86MqmF4eBibzYbT6eTDDz+ksLCQbdu2MW3an3/OHnzwQd566y1aWlr4/PPPyc7Oxt/ff8w5LVq0iPPnz1NbW0tPTw+lpaXU19dP+DfJzMykv7+f8vJy97bFsbz++uts3bqVxsZGenp66OjoYOfOnXR0dJCUlDSq/+DgIElJSVitVh5//HG+//5793Vt7FtuuYXk5GRaWlro7e3l5MmTbN++nb6+vgnPQUREJkbBSUREJsxms3HhwgUSEhJYsGCBuz0uLg6Hw0FtbS3Lly9n9+7dvPDCCx7h6sCBAzz88MPk5+ezZMkS8vLy3CstW7ZsITU1lYyMDO655x5+/vlnj9Wna9auXUtUVBTx8fGkp6eTlJTkcdT4888/T3x8PBs2bOChhx4iJSWFhQsXjjmf5ORkduzYwbZt27BarZw+fRq73T7h32PWrFmkpaVhGAYpKSnj9r377ru5dOkSW7ZsISYmhtWrV9Pa2kpDQ4PX//364Ycf+OKLL2hqamLu3LmEh4e7L4CgoCCam5tZsGABqampLF26lNzcXAYHB7UCJSJyHfiZ/7kZXERERCZs3bp1LF26lNLS0qkuRUREriMFJxERkUn45ZdfaGxsJDMzE6fTSXR09FSXJCIi15EOhxAREZmEuLg4Lly4wMsvv6zQJCLyf0ArTiIiIiIiIj7ocAgREREREREfFJxERERERER8UHASERERERHxQcFJRERERETEBwUnERERERERHxScREREREREfFBwEhERERER8UHBSURERERExIc/AG1YLW+ixAK2AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "\n", "tokens_length = len(new_text)\n", "\n", "original_length = len(text)\n", "\n", "print(f\"original length: {original_length}\")\n", "print(f\"tokens length: {tokens_length}\")\n", "print(f\"compression ratio: {tokens_length/original_length}\")\n", "\n", "\n", "def compression_ratio(text, new_vocab_size):\n", " new_text = text\n", " old_vocab_size = 256\n", " num_merges = new_vocab_size - old_vocab_size\n", " merge = {}\n", " for i in range(num_merges):\n", " counts = get_counts(new_text)\n", " top_pair = max(counts, key=counts.get)\n", " merge[top_pair] = i + old_vocab_size\n", " new_text = merge_token(top_pair, new_text, i + old_vocab_size)\n", " return len(new_text)/len(text)\n", "\n", "print(new_text[:50])\n", "\n", "import matplotlib.pyplot as plt\n", "\n", "def plot_compression_ratio(new_text, max_new_vocab_size):\n", " x = [] # New vocabulary sizes\n", " y = [] # Corresponding compression ratios\n", "\n", " for new_vocab_size in range(256, max_new_vocab_size + 1, 32):\n", " ratio = compression_ratio(text, new_vocab_size)\n", " x.append(new_vocab_size)\n", " y.append(ratio)\n", " print(f\"Vocab size: {new_vocab_size}, Compression Ratio: {ratio}\")\n", "\n", " plt.figure(figsize=(10, 6))\n", " plt.plot(x, y, marker='o')\n", " plt.title('Compression Ratio vs. Vocabulary Size')\n", " plt.xlabel('Vocabulary Size')\n", " plt.ylabel('Compression Ratio')\n", " plt.grid(True)\n", " plt.show()\n", "\n", "plot_compression_ratio(text, 1024)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'%'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "vocab = {i: bytes([i]) for i in range(256)}\n", "\n", "for (pair0, pair1), symbol in merge.items():\n", " \n", " vocab[symbol] = vocab[pair0] + vocab[pair1]\n", "\n", "\n", "\n", "\n", "def decode_sequence(sequence):\n", " bitstring = b\"\".join([vocab[token] for token in sequence])\n", " return bitstring.decode('utf-8', errors='replace')\n", "\n", "decode_sequence([37])\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{(101, 32): 256, (116, 32): 257, (116, 104): 258, (105, 110): 259, (44, 32): 260, (115, 32): 261, (111, 117): 262, (121, 32): 263, (101, 114): 264, (100, 32): 265, (97, 110): 266, (73, 32): 267, (32, 258): 268, (97, 32): 269, (111, 110): 270, (259, 39): 271, (111, 119): 272, (111, 32): 273, (108, 105): 274, (108, 108): 275, (99, 107): 276, (101, 97): 277, (121, 262): 278, (111, 114): 279, (101, 110): 280, (268, 256): 281, (271, 32): 282, (109, 32): 283, (101, 10): 284, (32, 109): 285, (104, 97): 286, (105, 116): 287, (73, 39): 288, (107, 256): 289, (259, 103): 290, (117, 115): 291, (101, 101): 292, (226, 128): 293, (118, 264): 294, (110, 272): 295, (105, 103): 296, (105, 261): 297, (278, 32): 298, (280, 32): 299, (105, 257): 300, (116, 273): 301, (115, 116): 302, (115, 104): 303, (274, 289): 304, (288, 283): 305, (99, 104): 306, (118, 256): 307, (108, 97): 308, (293, 153): 309, (266, 265): 310, (111, 100): 311, (10, 267): 312, (117, 276): 313, (258, 256): 314, (114, 97): 315, (101, 115): 316, (116, 105): 317, (102, 279): 318, (107, 295): 319, (109, 256): 320, (101, 294): 321, (97, 257): 322, (98, 101): 323, (97, 275): 324, (101, 257): 325, (117, 257): 326, (114, 111): 327, (41, 10): 328, (102, 313): 329, (119, 104): 330, (296, 104): 331, (290, 32): 332, (119, 105): 333, (100, 270): 334, (101, 260): 335, (103, 111): 336, (264, 32): 337, (109, 263): 338, (105, 99): 339, (97, 114): 340, (39, 261): 341, (111, 102): 342, (110, 269): 343, (117, 112): 344, (285, 263): 345, (97, 116): 346, (97, 261): 347, (266, 32): 348, (260, 267): 349, (115, 10): 350, (101, 265): 351, (108, 32): 352, (119, 266): 353, (110, 265): 354, (333, 258): 355, (108, 111): 356, (276, 32): 357, (100, 10): 358, (272, 32): 359, (114, 32): 360, (102, 292): 361, (98, 256): 362, (111, 109): 363, (39, 257): 364, (101, 263): 365, (319, 32): 366, (98, 311): 367, (291, 257): 368, (116, 10): 369, (98, 97): 370, (323, 299): 371, (367, 263): 372, (114, 277): 373, (108, 256): 374, (97, 108): 375, (110, 111): 376, (32, 269): 377, (97, 109): 378, (353, 343): 379, (93, 10): 380, (277, 104): 381, (260, 98): 382, (10, 66): 383, (10, 91): 384, (101, 261): 385, (87, 104): 386, (100, 105): 387, (65, 354): 388, (286, 116): 389, (111, 112): 390, (106, 368): 391, (275, 32): 392, (89, 262): 393, (108, 265): 394, (309, 257): 395, (111, 258): 396, (116, 116): 397, (321, 121): 398, (315, 112): 399, (117, 110): 400, (262, 257): 401, (97, 121): 402, (73, 83): 403, (109, 259): 404, (105, 100): 405, (111, 103): 406, (105, 115): 407, (114, 101): 408, (10, 84): 409, (103, 104): 410, (97, 115): 411, (258, 322): 412, (116, 101): 413, (117, 114): 414, (331, 257): 415, (103, 325): 416, (321, 32): 417, (104, 256): 418, (73, 309): 419, (274, 118): 420, (97, 263): 421, (116, 111): 422, (271, 257): 423, (334, 364): 424, (318, 32): 425, (272, 110): 426, (259, 281): 427, (97, 45): 428, (101, 118): 429, (264, 256): 430, (97, 100): 431, (334, 395): 432, (115, 273): 433, (10, 76): 434, (260, 119): 435, (306, 105): 436, (393, 32): 437, (114, 256): 438, (105, 275): 439, (97, 423): 440, (361, 352): 441, (270, 32): 442, (262, 410): 443, (268, 322): 444, (107, 32): 445, (342, 32): 446, (111, 111): 447, (270, 281): 448, (317, 109): 449, (284, 267): 450, (10, 388): 451, (258, 332): 452, (114, 105): 453, (286, 257): 454, (406, 339): 455, (10, 83): 456, (288, 109): 457, (262, 394): 458, (108, 272): 459, (99, 324): 460, (97, 98): 461, (101, 109): 462, (361, 108): 463, (121, 381): 464, (264, 115): 465, (318, 281): 466, (121, 260): 467, (419, 283): 468, (104, 359): 469, (296, 103): 470, (116, 97): 471, (274, 102): 472, (97, 259): 473, (303, 300): 474, (278, 360): 475, (264, 261): 476, (69, 294): 477, (287, 260): 478, (101, 283): 479, (389, 341): 480, (63, 10): 481, (258, 365): 482, (104, 277): 483, (67, 104): 484, (89, 381): 485, (108, 263): 486, (58, 32): 487, (46, 32): 488, (293, 148): 489, (100, 260): 490, (97, 99): 491, (441, 304): 492, (268, 297): 493, (259, 32): 494, (336, 257): 495, (326, 267): 496, (376, 257): 497, (99, 97): 498, (107, 282): 499, (370, 357): 500, (109, 266): 501, (76, 455): 502, (287, 10): 503, (100, 426): 504, (100, 264): 505, (108, 101): 506, (86, 465): 507, (116, 260): 508, (101, 275): 509, (121, 372): 510, (110, 273): 511, (112, 32): 512, (116, 114): 513, (103, 105): 514, (344, 32): 515, (98, 263): 516, (287, 306): 517, (10, 71): 518, (258, 346): 519, (102, 32): 520, (324, 32): 521, (110, 292): 522, (260, 305): 523, (403, 403): 524, (268, 365): 525, (330, 299): 526, (384, 507): 527, (105, 350): 528, (97, 10): 529, (422, 281): 530, (116, 261): 531, (457, 269): 532, (291, 256): 533, (398, 372): 534, (39, 438): 535, (112, 112): 536, (114, 331): 537, (110, 417): 538, (397, 269): 539, (102, 259): 540, (109, 279): 541, (102, 327): 542, (285, 256): 543, (100, 111): 544, (117, 109): 545, (100, 273): 546, (104, 297): 547, (436, 107): 548, (449, 385): 549, (329, 282): 550, (356, 307): 551, (308, 357): 552, (472, 256): 553, (115, 97): 554, (116, 264): 555, (104, 111): 556, (101, 256): 557, (527, 256): 558, (269, 115): 559, (103, 32): 560, (269, 109): 561, (256, 310): 562, (99, 348): 563, (379, 362): 564, (97, 420): 565, (270, 284): 566, (336, 539): 567, (330, 430): 568, (398, 452): 569, (110, 97): 570, (73, 110): 571, (100, 337): 572, (98, 108): 573, (277, 360): 574, (119, 454): 575, (111, 116): 576, (522, 265): 577, (10, 72): 578, (97, 260): 579, (39, 479): 580, (115, 260): 581, (258, 297): 582, (119, 279): 583, (307, 371): 584, (108, 325): 585, (99, 266): 586, (286, 265): 587, (316, 257): 588, (111, 265): 589, (101, 108): 590, (119, 347): 591, (287, 341): 592, (111, 320): 593, (108, 121): 594, (115, 105): 595, (114, 262): 596, (355, 32): 597, (484, 279): 598, (598, 291): 599, (119, 256): 600, (463, 282): 601, (428, 548): 602, (109, 284): 603, (386, 111): 604, (290, 260): 605, (329, 32): 606, (316, 115): 607, (312, 371): 608, (98, 326): 609, (355, 377): 610, (104, 260): 611, (285, 396): 612, (108, 277): 613, (97, 103): 614, (111, 98): 615, (100, 263): 616, (110, 470): 617, (270, 256): 618, (115, 112): 619, (39, 32): 620, (304, 269): 621, (477, 510): 622, (99, 256): 623, (63, 32): 624, (10, 386): 625, (317, 270): 626, (10, 70): 627, (66, 326): 628, (277, 114): 629, (99, 363): 630, (10, 78): 631, (110, 101): 632, (98, 517): 633, (498, 533): 634, (487, 502): 635, (370, 276): 636, (10, 77): 637, (101, 390): 638, (105, 108): 639, (278, 535): 640, (99, 262): 641, (524, 260): 642, (480, 344): 643, (338, 404): 644, (308, 413): 645, (121, 10): 646, (363, 101): 647, (340, 256): 648, (105, 114): 649, (100, 114): 650, (114, 415): 651, (262, 369): 652, (429, 299): 653, (104, 32): 654, (542, 283): 655, (329, 476): 656, (313, 32): 657, (262, 354): 658, (111, 294): 659, (355, 281): 660, (103, 273): 661, (107, 284): 662, (268, 346): 663, (107, 439): 664, (107, 105): 665, (373, 306): 666, (604, 97): 667, (320, 416): 668, (115, 647): 669, (109, 335): 670, (309, 261): 671, (104, 363): 672, (258, 290): 673, (513, 121): 674, (286, 114): 675, (116, 327): 676, (259, 345): 677, (382, 326): 678, (435, 256): 679, (344, 260): 680, (399, 32): 681, (111, 107): 682, (10, 393): 683, (100, 101): 684, (596, 110): 685, (519, 341): 686, (384, 599): 687, (118, 105): 688, (303, 287): 689, (10, 79): 690, (317, 320): 691, (40, 66): 692, (102, 491): 693, (98, 277): 694, (40, 87): 695, (303, 458): 696, (71, 311): 697, (40, 667): 698, (447, 33): 699, (668, 644): 700, (342, 345): 701, (73, 257): 702, (473, 395): 703, (10, 65): 704, (396, 337): 705, (112, 308): 706, (10, 437): 707, (324, 263): 708, (330, 273): 709, (514, 307): 710, (41, 312): 711, (118, 282): 712, (304, 258): 713, (119, 270): 714, (116, 282): 715, (110, 32): 716, (518, 325): 717, (276, 101): 718, (108, 359): 719, (119, 421): 720, (119, 402): 721, (270, 345): 722, (39, 634): 723, (635, 380): 724, (602, 602): 725, (383, 326): 726, (103, 270): 727, (111, 121): 728, (316, 256): 729, (112, 638): 730, (99, 458): 731, (351, 301): 732, (308, 276): 733, (270, 486): 734, (308, 307): 735, (698, 328): 736, (399, 382): 737, (109, 348): 738, (379, 387): 739, (270, 101): 740, (461, 401): 741, (274, 410): 742, (258, 264): 743, (108, 100): 744, (108, 270): 745, (674, 343): 746, (266, 121): 747, (526, 267): 748, (264, 656): 749, (340, 658): 750, (434, 105): 751, (302, 390): 752, (681, 303): 753, (66, 327): 754, (317, 718): 755, (755, 531): 756, (52, 48): 757, (375, 433): 758, (274, 662): 759, (105, 109): 760, (615, 516): 761, (97, 289): 762, (464, 260): 763, (104, 300): 764, (111, 394): 765, (101, 392): 766, (295, 32): 767, (10, 485): 768, (296, 32): 769, (107, 292): 770, (271, 260): 771, (267, 109): 772, (483, 114): 773, (266, 100): 774, (356, 118): 775, (97, 329): 776, (114, 605): 777, (286, 109): 778, (10, 87): 779, (303, 32): 780, (549, 466): 781, (642, 642): 782, (260, 338): 783, (434, 325): 784, (492, 338): 785, (107, 259): 786, (258, 259): 787, (104, 264): 788, (409, 104): 789, (115, 257): 790, (256, 40): 791, (267, 115): 792, (384, 571): 793, (713, 528): 794, (287, 256): 795, (612, 749): 796, (101, 100): 797, (271, 268): 798, (114, 443): 799, (108, 117): 800, (102, 117): 801, (100, 378): 802, (557, 753): 803, (803, 272): 804, (804, 261): 805, (805, 110): 806, (806, 574): 807, (807, 754): 808, (808, 682): 809, (809, 594): 810, (810, 110): 811, (811, 717): 812, (812, 756): 813, (813, 347): 814, (814, 719): 815, (815, 347): 816, (816, 36): 817, (817, 757): 818, (818, 683): 819, (819, 285): 820, (820, 415): 821, (821, 758): 822, (822, 759): 823, (306, 266): 824, (382, 496): 825, (471, 289): 826, (114, 292): 827, (99, 315): 828, (101, 397): 829, (301, 98): 830, (112, 114): 831, (586, 364): 832, (105, 107): 833, (117, 99): 834, (259, 377): 835, (406, 32): 836, (302, 105): 837, (288, 584): 838, (777, 777): 839, (10, 622): 840, (695, 699): 841, (121, 349): 842, (537, 369): 843, (562, 541): 844, (339, 576): 845, (845, 259): 846, (297, 375): 847, (358, 702): 848, (785, 553): 849, (565, 450): 850, (429, 280): 851, (312, 366): 852, (278, 114): 853, (353, 257): 854, (284, 78): 855, (400, 505): 856, (331, 116): 857, (383, 496): 858, (76, 105): 859, (119, 114): 860, (356, 111): 861, (100, 402): 862, (70, 657): 863, (672, 105): 864, (99, 593): 865, (105, 374): 866, (316, 260): 867, (310, 314): 868, (111, 257): 869, (97, 102): 870, (116, 588): 871, (389, 256): 872, (114, 400): 873, (279, 32): 874, (420, 282): 875, (39, 462): 876, (102, 378): 877, (67, 97): 878, (402, 362): 879, (101, 341): 880, (115, 109): 881, (110, 364): 882, (98, 111): 883, (65, 121): 884, (100, 103): 885, (80, 666): 886, (286, 307): 887, (112, 105): 888, (469, 301): 889, (335, 534): 890, (841, 328): 891, (836, 39): 892, (892, 685): 893, (893, 100): 894, (894, 489): 895, (655, 97): 896, (896, 489): 897, (74, 316): 898, (595, 302): 899, (115, 270): 900, (569, 847): 901, (419, 584): 902, (107, 290): 903, (492, 468): 904, (401, 701): 905, (404, 284): 906, (116, 375): 907, (112, 315): 908, (303, 359): 909, (376, 372): 910, (789, 365): 911, (115, 421): 912, (298, 301): 913, (625, 299): 914, (316, 261): 915, (71, 589): 916, (568, 298): 917, (274, 397): 918, (918, 374): 919, (540, 708): 920, (676, 380): 921, (10, 558): 922, (370, 98): 923, (427, 99): 924, (331, 369): 925, (802, 110): 926, (301, 109): 927, (116, 390): 928, (115, 593): 929, (83, 823): 930, (632, 119): 931, (98, 356): 932, (109, 396): 933, (269, 98): 934, (268, 443): 935, (114, 405): 936, (101, 99): 937, (280, 265): 938, (117, 116): 939, (334, 256): 940, (630, 282): 941, (303, 503): 942, (493, 474): 943, (84, 104): 944, (115, 256): 945, (304, 314): 946, (114, 272): 947, (730, 374): 948, (109, 281): 949, (516, 314): 950, (10, 305): 951, (112, 291): 952, (271, 281): 953, (614, 473): 954, (297, 314): 955, (346, 116): 956, (10, 68): 957, (336, 282): 958, (884, 121): 959, (349, 371): 960, (121, 111): 961, (961, 620): 962, (83, 112): 963, (97, 302): 964, (116, 351): 965, (407, 105): 966, (573, 292): 967, (112, 264): 968, (318, 268): 969, (85, 611): 970, (100, 97): 971, (844, 844): 972, (83, 101): 973, (902, 448): 974, (974, 459): 975, (608, 471): 976, (976, 903): 977, (977, 345): 978, (978, 449): 979, (979, 450): 980, (980, 904): 981, (981, 905): 982, (982, 404): 983, (983, 848): 984, (984, 849): 985, (985, 703): 986, (986, 906): 987, (116, 311): 988, (413, 392): 989, (98, 401): 990, (787, 107): 991, (112, 104): 992, (853, 285): 993, (99, 105): 994, (565, 284): 995, (10, 73): 996, (102, 649): 997, (98, 373): 998, (275, 268): 999, (100, 421): 1000, (651, 295): 1001, (920, 564): 1002, (409, 418): 1003, (111, 118): 1004, (103, 261): 1005, (114, 263): 1006, (336, 589): 1007, (260, 298): 1008, (112, 327): 1009, (363, 109): 1010, (413, 275): 1011, (275, 263): 1012, (98, 105): 1013, (281, 110): 1014, (99, 340): 1015, (256, 298): 1016, (613, 307): 1017, (111, 260): 1018, (376, 260): 1019, (266, 705): 1020, (121, 629): 1021, (105, 258): 1022, (66, 761): 1023}\n" ] } ], "source": [ "print(merge)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[402, 121, 121, 263, 119, 389, 261, 515, 240, 159, 145, 139]\n" ] } ], "source": [ "def encode_sequence(sequence):\n", " tokens = list(sequence.encode('utf-8'))\n", " \n", " \n", " while len(tokens) >= 2:\n", " counts = get_counts(tokens)\n", " pair = min(counts, key=lambda x: merge.get(x, float('inf')))\n", " # print(pair)\n", " # print(merge)\n", " if pair not in merge:\n", " break\n", " \n", " symbol = merge[pair]\n", " tokens = merge_token(pair, tokens, symbol)\n", " return tokens\n", "\n", "\n", "\n", "print(encode_sequence(\"ayyyy whats up 👋\"))\n", "\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ayyyy whats up 👋\n", "['h', 'ell', 'o']\n" ] } ], "source": [ "print(decode_sequence(encode_sequence(\"ayyyy whats up 👋\")))\n", "\n", "\n", "token_delimited_text = [decode_sequence([token]) for token in encode_sequence(\"hello\")]\n", "print(token_delimited_text)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[104, 509, 111]\n" ] } ], "source": [ "print(encode_sequence(\"hello\"))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['shit']\n" ] } ], "source": [ "print([decode_sequence([token]) for token in encode_sequence(\"shit\")])" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['S', 'it ', 'the ', 'fuck ', 'back ', 'down']\n", "compression ratio: 3.6666666666666665\n" ] } ], "source": [ "print([decode_sequence([token]) for token in encode_sequence(\"Sit the fuck back down\")])\n", "print(f\"compression ratio: {len('Sit the fuck back down')/len([decode_sequence([token]) for token in encode_sequence('Sit the fuck back down')])}\")\n", "\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "Object of type bytes is not JSON serializable", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[16], line 8\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m# for key, value in vocab.items():\u001b[39;00m\n\u001b[1;32m 4\u001b[0m \n\u001b[1;32m 5\u001b[0m \u001b[38;5;66;03m# vocab[key] = value.decode('utf-8', errors='replace')\u001b[39;00m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvocab.json\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m json_file:\n\u001b[0;32m----> 8\u001b[0m \u001b[43mjson\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdump\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvocab\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mjson_file\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 10\u001b[0m merge_untupled \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mjoin(\u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28mstr\u001b[39m, key)): value \u001b[38;5;28;01mfor\u001b[39;00m key, value \u001b[38;5;129;01min\u001b[39;00m merge\u001b[38;5;241m.\u001b[39mitems()}\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmerge.json\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m json_file:\n", "File \u001b[0;32m~/miniforge3/envs/gradio/lib/python3.10/json/__init__.py:179\u001b[0m, in \u001b[0;36mdump\u001b[0;34m(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)\u001b[0m\n\u001b[1;32m 173\u001b[0m iterable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mcls\u001b[39m(skipkeys\u001b[38;5;241m=\u001b[39mskipkeys, ensure_ascii\u001b[38;5;241m=\u001b[39mensure_ascii,\n\u001b[1;32m 174\u001b[0m check_circular\u001b[38;5;241m=\u001b[39mcheck_circular, allow_nan\u001b[38;5;241m=\u001b[39mallow_nan, indent\u001b[38;5;241m=\u001b[39mindent,\n\u001b[1;32m 175\u001b[0m separators\u001b[38;5;241m=\u001b[39mseparators,\n\u001b[1;32m 176\u001b[0m default\u001b[38;5;241m=\u001b[39mdefault, sort_keys\u001b[38;5;241m=\u001b[39msort_keys, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkw)\u001b[38;5;241m.\u001b[39miterencode(obj)\n\u001b[1;32m 177\u001b[0m \u001b[38;5;66;03m# could accelerate with writelines in some versions of Python, at\u001b[39;00m\n\u001b[1;32m 178\u001b[0m \u001b[38;5;66;03m# a debuggability cost\u001b[39;00m\n\u001b[0;32m--> 179\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m chunk \u001b[38;5;129;01min\u001b[39;00m iterable:\n\u001b[1;32m 180\u001b[0m fp\u001b[38;5;241m.\u001b[39mwrite(chunk)\n", "File \u001b[0;32m~/miniforge3/envs/gradio/lib/python3.10/json/encoder.py:431\u001b[0m, in \u001b[0;36m_make_iterencode.._iterencode\u001b[0;34m(o, _current_indent_level)\u001b[0m\n\u001b[1;32m 429\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m _iterencode_list(o, _current_indent_level)\n\u001b[1;32m 430\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(o, \u001b[38;5;28mdict\u001b[39m):\n\u001b[0;32m--> 431\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m _iterencode_dict(o, _current_indent_level)\n\u001b[1;32m 432\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 433\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m markers \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", "File \u001b[0;32m~/miniforge3/envs/gradio/lib/python3.10/json/encoder.py:405\u001b[0m, in \u001b[0;36m_make_iterencode.._iterencode_dict\u001b[0;34m(dct, _current_indent_level)\u001b[0m\n\u001b[1;32m 403\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 404\u001b[0m chunks \u001b[38;5;241m=\u001b[39m _iterencode(value, _current_indent_level)\n\u001b[0;32m--> 405\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m chunks\n\u001b[1;32m 406\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m newline_indent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 407\u001b[0m _current_indent_level \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n", "File \u001b[0;32m~/miniforge3/envs/gradio/lib/python3.10/json/encoder.py:438\u001b[0m, in \u001b[0;36m_make_iterencode.._iterencode\u001b[0;34m(o, _current_indent_level)\u001b[0m\n\u001b[1;32m 436\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCircular reference detected\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 437\u001b[0m markers[markerid] \u001b[38;5;241m=\u001b[39m o\n\u001b[0;32m--> 438\u001b[0m o \u001b[38;5;241m=\u001b[39m \u001b[43m_default\u001b[49m\u001b[43m(\u001b[49m\u001b[43mo\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 439\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m _iterencode(o, _current_indent_level)\n\u001b[1;32m 440\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m markers \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", "File \u001b[0;32m~/miniforge3/envs/gradio/lib/python3.10/json/encoder.py:179\u001b[0m, in \u001b[0;36mJSONEncoder.default\u001b[0;34m(self, o)\u001b[0m\n\u001b[1;32m 160\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdefault\u001b[39m(\u001b[38;5;28mself\u001b[39m, o):\n\u001b[1;32m 161\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Implement this method in a subclass such that it returns\u001b[39;00m\n\u001b[1;32m 162\u001b[0m \u001b[38;5;124;03m a serializable object for ``o``, or calls the base implementation\u001b[39;00m\n\u001b[1;32m 163\u001b[0m \u001b[38;5;124;03m (to raise a ``TypeError``).\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 177\u001b[0m \n\u001b[1;32m 178\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 179\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mObject of type \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mo\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 180\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mis not JSON serializable\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", "\u001b[0;31mTypeError\u001b[0m: Object of type bytes is not JSON serializable" ] } ], "source": [ "import json\n", "\n", "# for key, value in vocab.items():\n", " \n", "# vocab[key] = value.decode('utf-8', errors='replace')\n", "\n", "with open('vocab.json', 'w') as json_file:\n", " json.dump(vocab, json_file)\n", " \n", "merge_untupled = {'_'.join(map(str, key)): value for key, value in merge.items()}\n", "\n", "with open('merge.json', 'w') as json_file:\n", " json.dump(merge_untupled, json_file)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "gradio", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 2 }