mirror of
https://github.com/ArthurDanjou/ArtStudies.git
synced 2026-03-16 05:11:40 +01:00
- Updated pyproject.toml to include "tiktoken>=0.12.0" in dependencies. - Modified uv.lock to reflect the addition of tiktoken in both dependencies and requires-dist sections.
2126 lines
206 KiB
Plaintext
2126 lines
206 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "header",
|
|
"metadata": {},
|
|
"source": [
|
|
"# 🔤 Understanding Tokenization with TikToken\n",
|
|
"## A Deep Dive into How LLMs Process Text\n",
|
|
"\n",
|
|
"<div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 15px; color: white; text-align: center;\">\n",
|
|
" <h2>🧠 Learn How AI \"Reads\" Text</h2>\n",
|
|
" <p>Discover the fascinating world of tokenization and why it matters for AI applications</p>\n",
|
|
"</div>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 🎯 What You'll Learn\n",
|
|
"\n",
|
|
"| Topic | Description | Key Insight |\n",
|
|
"|-------|-------------|-------------|\n",
|
|
"| **Basics** | What are tokens and why they matter | Understanding the fundamental unit of LLMs |\n",
|
|
"| **Word Breaking** | How text gets split into pieces | See tokenization in action |\n",
|
|
"| **Language Efficiency** | English vs French token usage | Not all languages are equal! |\n",
|
|
"| **Format Comparison** | JSON vs YAML tokenization | Choose the right format to save tokens |\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 🤔 Why Does Tokenization Matter?\n",
|
|
"\n",
|
|
"```\n",
|
|
"Your Text → Tokenization → AI Model → Response\n",
|
|
" │ │ │ │\n",
|
|
" │ │ │ │\n",
|
|
"\"Hello!\" [9906, 0] Processing Generation\n",
|
|
"```\n",
|
|
"\n",
|
|
"### Key Reasons to Understand Tokenization:\n",
|
|
"\n",
|
|
"1. **💰 Cost**: Most APIs charge per token, not per word\n",
|
|
"2. **📏 Limits**: Models have token limits (e.g., 128K tokens for GPT-4)\n",
|
|
"3. **⚡ Performance**: Fewer tokens = faster processing\n",
|
|
"4. **🌍 Language**: Different languages use different token counts\n",
|
|
"5. **📊 Format**: Data structure choices impact token efficiency\n",
|
|
"\n",
|
|
"---"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "imports",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"✅ All imports successful!\n",
|
|
"📚 TikToken version: 0.12.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import json\n",
|
|
"\n",
|
|
"import tiktoken\n",
|
|
"import yaml\n",
|
|
"\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"print(\"✅ All imports successful!\")\n",
|
|
"print(f\"📚 TikToken version: {tiktoken.__version__}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "part1",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"# 🎬 Part 1: Tokenization Basics\n",
|
|
"\n",
|
|
"<div style=\"background-color:rgb(66, 148, 206); padding: 20px; border-left: 5px solid #2196F3; border-radius: 5px;\">\n",
|
|
" <h3>🎯 Learning Objectives</h3>\n",
|
|
" <ul>\n",
|
|
" <li>Understand what tokens are</li>\n",
|
|
" <li>Learn how to initialize TikToken encoders</li>\n",
|
|
" <li>See basic encoding and decoding examples</li>\n",
|
|
" </ul>\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "what-are-tokens",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🔍 What Are Tokens?\n",
|
|
"\n",
|
|
"Tokens are the **fundamental units** that language models work with. They're not quite words, and not quite characters!\n",
|
|
"\n",
|
|
"### Key Concepts:\n",
|
|
"\n",
|
|
"- 🔤 **1 token ≈ 4 characters** in English\n",
|
|
"- 📝 **1 token ≈ ¾ of a word** on average\n",
|
|
"- 🌐 **Different for each language** (English is most efficient)\n",
|
|
"- 🔢 **Each token has a unique ID** (integer)\n",
|
|
"\n",
|
|
"### Examples:\n",
|
|
"\n",
|
|
"```\n",
|
|
"\"Hello\" → 1 token [9906]\n",
|
|
"\"Hello World\" → 2 tokens [9906, 4435]\n",
|
|
"\"tokenization\" → 2 tokens [5963, 2065]\n",
|
|
"\"AI\" → 1 token [15836]\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "initialize-encoder",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🔧 Initialize the Tokenizer\n",
|
|
"\n",
|
|
"Different models use different tokenizers. Let's load the one used by GPT-4:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "load-encoder",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"✅ Encoder loaded successfully!\n",
|
|
"📊 Encoding name: cl100k_base\n",
|
|
"🔢 Vocabulary size: 100,277 tokens\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Load the cl100k_base encoding used by GPT-4 and GPT-3.5-turbo\n",
|
|
"encoding = tiktoken.get_encoding(\"cl100k_base\")\n",
|
|
"\n",
|
|
"# Alternative: Load by model name\n",
|
|
"# encoding = tiktoken.encoding_for_model(\"gpt-4\") # noqa: ERA001\n",
|
|
"\n",
|
|
"print(\"✅ Encoder loaded successfully!\")\n",
|
|
"print(f\"📊 Encoding name: {encoding.name}\")\n",
|
|
"print(f\"🔢 Vocabulary size: {encoding.n_vocab:,} tokens\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "basic-encoding",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🎨 Your First Encoding Example\n",
|
|
"\n",
|
|
"Let's see how a simple sentence gets tokenized:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "first-example",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"📝 Original Text:\n",
|
|
" Hello, how are you today?\n",
|
|
"\n",
|
|
"🔢 Token IDs:\n",
|
|
" [9906, 11, 1268, 527, 499, 3432, 30]\n",
|
|
"\n",
|
|
"📊 Number of tokens: 7\n",
|
|
"\n",
|
|
"🔄 Decoded Text:\n",
|
|
" Hello, how are you today?\n",
|
|
"\n",
|
|
"✅ Match: True\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# A simple sentence\n",
|
|
"text = \"Hello, how are you today?\"\n",
|
|
"\n",
|
|
"# Encode to token IDs\n",
|
|
"tokens = encoding.encode(text)\n",
|
|
"\n",
|
|
"# Decode back to text\n",
|
|
"decoded_text = encoding.decode(tokens)\n",
|
|
"\n",
|
|
"print(\"📝 Original Text:\")\n",
|
|
"print(f\" {text}\")\n",
|
|
"print(\"\\n🔢 Token IDs:\")\n",
|
|
"print(f\" {tokens}\")\n",
|
|
"print(f\"\\n📊 Number of tokens: {len(tokens)}\")\n",
|
|
"print(\"\\n🔄 Decoded Text:\")\n",
|
|
"print(f\" {decoded_text}\")\n",
|
|
"print(f\"\\n✅ Match: {text == decoded_text}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "utility-functions",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🛠️ Utility Functions\n",
|
|
"\n",
|
|
"Let's create some helpful functions for our analysis:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "helper-functions",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"✅ Utility functions defined!\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def count_tokens(text: str, encoding: tiktoken.Encoding = encoding) -> int:\n",
|
|
" \"\"\"Count the number of tokens in a text.\"\"\"\n",
|
|
" return len(encoding.encode(text))\n",
|
|
"\n",
|
|
"\n",
|
|
"def visualize_tokens(text: str, encoding: tiktoken.Encoding = encoding) -> None:\n",
|
|
" \"\"\"Visualize how text is broken into tokens.\"\"\"\n",
|
|
" tokens = encoding.encode(text)\n",
|
|
"\n",
|
|
" print(f\"\\n{'=' * 70}\")\n",
|
|
" print(f\"Text: {text}\")\n",
|
|
" print(f\"{'=' * 70}\")\n",
|
|
" print(f\"Total tokens: {len(tokens)}\\n\")\n",
|
|
"\n",
|
|
" for i, token in enumerate(tokens, 1):\n",
|
|
" decoded = encoding.decode([token])\n",
|
|
" # Replace newlines and special chars for visibility\n",
|
|
" decoded_display = decoded.replace(\"\\n\", \"\\\\n\").replace(\"\\t\", \"\\\\t\")\n",
|
|
" print(f\"Token {i:2d}: {token:6d} → '{decoded_display}'\")\n",
|
|
"\n",
|
|
" print(f\"{'=' * 70}\\n\")\n",
|
|
"\n",
|
|
"\n",
|
|
"def compare_texts(\n",
|
|
" texts: dict[str, str],\n",
|
|
" encoding: tiktoken.Encoding = encoding,\n",
|
|
") -> list[dict[str, object]]:\n",
|
|
" \"\"\"Compare token counts for multiple texts.\"\"\"\n",
|
|
" results = []\n",
|
|
"\n",
|
|
" print(f\"\\n{'=' * 70}\")\n",
|
|
" print(\"📊 Token Count Comparison\")\n",
|
|
" print(f\"{'=' * 70}\\n\")\n",
|
|
"\n",
|
|
" for label, text in texts.items():\n",
|
|
" token_count = count_tokens(text, encoding)\n",
|
|
" char_count = len(text)\n",
|
|
" ratio = char_count / token_count if token_count > 0 else 0\n",
|
|
"\n",
|
|
" results.append(\n",
|
|
" {\n",
|
|
" \"label\": label,\n",
|
|
" \"tokens\": token_count,\n",
|
|
" \"chars\": char_count,\n",
|
|
" \"ratio\": ratio,\n",
|
|
" },\n",
|
|
" )\n",
|
|
"\n",
|
|
" print(f\"{label}:\")\n",
|
|
" print(f\" 📝 Text: {text[:60]}{'...' if len(text) > 60 else ''}\") # noqa: PLR2004\n",
|
|
" print(f\" 🔢 Tokens: {token_count}\")\n",
|
|
" print(f\" 📏 Characters: {char_count}\")\n",
|
|
" print(f\" 📊 Chars per token: {ratio:.2f}\")\n",
|
|
" print()\n",
|
|
"\n",
|
|
" return results\n",
|
|
"\n",
|
|
"\n",
|
|
"print(\"✅ Utility functions defined!\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "part2",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"# 🔨 Part 2: How Text Gets Broken Into Pieces\n",
|
|
"\n",
|
|
"<div style=\"background-color:rgb(195, 103, 210); padding: 20px; border-left: 5px solid #9c27b0; border-radius: 5px;\">\n",
|
|
" <h3>🎯 Learning Objectives</h3>\n",
|
|
" <ul>\n",
|
|
" <li>Visualize word breaking and subword units</li>\n",
|
|
" <li>Understand common vs rare word tokenization</li>\n",
|
|
" <li>See how punctuation and special characters are handled</li>\n",
|
|
" </ul>\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "word-breaking",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🔍 Common Words vs Rare Words\n",
|
|
"\n",
|
|
"Common words typically get their own token, while rare or complex words get split:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "common-vs-rare",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"📗 COMMON WORDS (Usually 1 token)\n",
|
|
"\n",
|
|
" 'hello ' → 1 token(s): [15339]\n",
|
|
" 'world ' → 1 token(s): [14957]\n",
|
|
" 'Python ' → 1 token(s): [31380]\n",
|
|
" 'computer ' → 1 token(s): [44211]\n",
|
|
" 'the ' → 1 token(s): [1820]\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"📕 RARE/COMPLEX WORDS (Multiple tokens)\n",
|
|
"\n",
|
|
" 'tokenization ' → 2 token(s)\n",
|
|
" Pieces: 'token' | 'ization'\n",
|
|
"\n",
|
|
" 'antidisestablishmentarianism ' → 6 token(s)\n",
|
|
" Pieces: 'ant' | 'idis' | 'establish' | 'ment' | 'arian' | 'ism'\n",
|
|
"\n",
|
|
" 'cryptocurrency ' → 2 token(s)\n",
|
|
" Pieces: 'crypt' | 'ocurrency'\n",
|
|
"\n",
|
|
" 'TikToken ' → 3 token(s)\n",
|
|
" Pieces: 'T' | 'ik' | 'Token'\n",
|
|
"\n",
|
|
" 'GPT-4 ' → 4 token(s)\n",
|
|
" Pieces: 'G' | 'PT' | '-' | '4'\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Common words (usually 1 token each)\n",
|
|
"common_examples = [\n",
|
|
" \"hello\",\n",
|
|
" \"world\",\n",
|
|
" \"Python\",\n",
|
|
" \"computer\",\n",
|
|
" \"the\",\n",
|
|
"]\n",
|
|
"\n",
|
|
"print(\"📗 COMMON WORDS (Usually 1 token)\\n\")\n",
|
|
"for word in common_examples:\n",
|
|
" tokens = encoding.encode(word)\n",
|
|
" print(f\" '{word:12s}' → {len(tokens)} token(s): {tokens}\")\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70 + \"\\n\")\n",
|
|
"\n",
|
|
"# Rare/complex words (usually multiple tokens)\n",
|
|
"rare_examples = [\n",
|
|
" \"tokenization\",\n",
|
|
" \"antidisestablishmentarianism\",\n",
|
|
" \"cryptocurrency\",\n",
|
|
" \"TikToken\",\n",
|
|
" \"GPT-4\",\n",
|
|
"]\n",
|
|
"\n",
|
|
"print(\"📕 RARE/COMPLEX WORDS (Multiple tokens)\\n\")\n",
|
|
"for word in rare_examples:\n",
|
|
" tokens = encoding.encode(word)\n",
|
|
" token_pieces = [encoding.decode([t]) for t in tokens]\n",
|
|
" print(f\" '{word:30s}' → {len(tokens)} token(s)\")\n",
|
|
" print(f\" Pieces: {' | '.join(repr(p) for p in token_pieces)}\")\n",
|
|
" print()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "detailed-breakdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🎨 Detailed Token Breakdown\n",
|
|
"\n",
|
|
"Let's see exactly how different types of text get tokenized:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "breakdown-examples",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: The quick brown fox jumps over the lazy dog.\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 10\n",
|
|
"\n",
|
|
"Token 1: 791 → 'The'\n",
|
|
"Token 2: 4062 → ' quick'\n",
|
|
"Token 3: 14198 → ' brown'\n",
|
|
"Token 4: 39935 → ' fox'\n",
|
|
"Token 5: 35308 → ' jumps'\n",
|
|
"Token 6: 927 → ' over'\n",
|
|
"Token 7: 279 → ' the'\n",
|
|
"Token 8: 16053 → ' lazy'\n",
|
|
"Token 9: 5679 → ' dog'\n",
|
|
"Token 10: 13 → '.'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 1: Simple sentence\n",
|
|
"visualize_tokens(\"The quick brown fox jumps over the lazy dog.\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"id": "breakdown-punctuation",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: Hello! How are you? I'm fine, thanks.\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 12\n",
|
|
"\n",
|
|
"Token 1: 9906 → 'Hello'\n",
|
|
"Token 2: 0 → '!'\n",
|
|
"Token 3: 2650 → ' How'\n",
|
|
"Token 4: 527 → ' are'\n",
|
|
"Token 5: 499 → ' you'\n",
|
|
"Token 6: 30 → '?'\n",
|
|
"Token 7: 358 → ' I'\n",
|
|
"Token 8: 2846 → ''m'\n",
|
|
"Token 9: 7060 → ' fine'\n",
|
|
"Token 10: 11 → ','\n",
|
|
"Token 11: 9523 → ' thanks'\n",
|
|
"Token 12: 13 → '.'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 2: Punctuation and special characters\n",
|
|
"visualize_tokens(\"Hello! How are you? I'm fine, thanks.\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"id": "breakdown-code",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: def hello_world(): print('Hello!')\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 9\n",
|
|
"\n",
|
|
"Token 1: 755 → 'def'\n",
|
|
"Token 2: 24748 → ' hello'\n",
|
|
"Token 3: 32892 → '_world'\n",
|
|
"Token 4: 4658 → '():'\n",
|
|
"Token 5: 1194 → ' print'\n",
|
|
"Token 6: 493 → '(''\n",
|
|
"Token 7: 9906 → 'Hello'\n",
|
|
"Token 8: 0 → '!'\n",
|
|
"Token 9: 873 → '')'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 3: Code-like text\n",
|
|
"visualize_tokens(\"def hello_world(): print('Hello!')\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"id": "breakdown-numbers",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: The year 2024 and the number 123,456.78\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 14\n",
|
|
"\n",
|
|
"Token 1: 791 → 'The'\n",
|
|
"Token 2: 1060 → ' year'\n",
|
|
"Token 3: 220 → ' '\n",
|
|
"Token 4: 2366 → '202'\n",
|
|
"Token 5: 19 → '4'\n",
|
|
"Token 6: 323 → ' and'\n",
|
|
"Token 7: 279 → ' the'\n",
|
|
"Token 8: 1396 → ' number'\n",
|
|
"Token 9: 220 → ' '\n",
|
|
"Token 10: 4513 → '123'\n",
|
|
"Token 11: 11 → ','\n",
|
|
"Token 12: 10961 → '456'\n",
|
|
"Token 13: 13 → '.'\n",
|
|
"Token 14: 2495 → '78'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 4: Numbers and dates\n",
|
|
"visualize_tokens(\"The year 2024 and the number 123,456.78\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"id": "4748a758",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: 13+27=40\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 5\n",
|
|
"\n",
|
|
"Token 1: 1032 → '13'\n",
|
|
"Token 2: 10 → '+'\n",
|
|
"Token 3: 1544 → '27'\n",
|
|
"Token 4: 28 → '='\n",
|
|
"Token 5: 1272 → '40'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 5: Numbers and dates\n",
|
|
"visualize_tokens(\"13+27=40\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"id": "35aef279",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: 13000+27=13027\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 7\n",
|
|
"\n",
|
|
"Token 1: 5894 → '130'\n",
|
|
"Token 2: 410 → '00'\n",
|
|
"Token 3: 10 → '+'\n",
|
|
"Token 4: 1544 → '27'\n",
|
|
"Token 5: 28 → '='\n",
|
|
"Token 6: 5894 → '130'\n",
|
|
"Token 7: 1544 → '27'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 5: Numbers and dates\n",
|
|
"visualize_tokens(\"13000+27=13027\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "interesting-patterns",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🔎 Interesting Tokenization Patterns\n",
|
|
"\n",
|
|
"### Pattern 1: Spaces Matter! 🌟"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"id": "space-patterns",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"🔍 How spaces affect tokenization:\n",
|
|
"\n",
|
|
" 'world' → [14957]\n",
|
|
" ' world' → [1917]\n",
|
|
" ' world' → [220, 1917]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Leading spaces change tokenization\n",
|
|
"examples = [\n",
|
|
" \"world\", # No space\n",
|
|
" \" world\", # With space\n",
|
|
" \" world\", # Two spaces\n",
|
|
"]\n",
|
|
"\n",
|
|
"print(\"🔍 How spaces affect tokenization:\\n\")\n",
|
|
"for example in examples:\n",
|
|
" tokens = encoding.encode(example)\n",
|
|
" print(f\" '{example}' → {tokens}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "pattern-2",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Pattern 2: Case Sensitivity 🔠"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"id": "case-patterns",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"🔍 Case sensitivity in tokenization:\n",
|
|
"\n",
|
|
" 'HELLO ' → [51812, 1623]\n",
|
|
" 'Hello ' → [9906]\n",
|
|
" 'hello ' → [15339]\n",
|
|
" 'HeLLo ' → [1548, 4178, 78]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Different cases = different tokens\n",
|
|
"examples = [\n",
|
|
" \"HELLO\",\n",
|
|
" \"Hello\",\n",
|
|
" \"hello\",\n",
|
|
" \"HeLLo\",\n",
|
|
"]\n",
|
|
"\n",
|
|
"print(\"🔍 Case sensitivity in tokenization:\\n\")\n",
|
|
"for example in examples:\n",
|
|
" tokens = encoding.encode(example)\n",
|
|
" print(f\" '{example:8s}' → {tokens}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "pattern-3",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Pattern 3: Emojis and Unicode 😊🎉"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"id": "emoji-patterns",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"🔍 Emojis and Unicode characters:\n",
|
|
"\n",
|
|
" 'Hello 😊 ' → 3 token(s): [9906, 27623, 232]\n",
|
|
" '🎉🎊🎈 ' → 9 token(s): [9468, 236, 231, 9468, 236, 232, 9468, 236, 230]\n",
|
|
" 'Python 🐍 ' → 4 token(s): [31380, 11410, 238, 235]\n",
|
|
" 'café ' → 2 token(s): [936, 59958]\n",
|
|
" '中文 ' → 2 token(s): [16325, 17161]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Emojis often take multiple tokens\n",
|
|
"examples = [\n",
|
|
" \"Hello 😊\",\n",
|
|
" \"🎉🎊🎈\",\n",
|
|
" \"Python 🐍\",\n",
|
|
" \"café\", # Accented character\n",
|
|
" \"中文\", # Chinese characters\n",
|
|
"]\n",
|
|
"\n",
|
|
"print(\"🔍 Emojis and Unicode characters:\\n\")\n",
|
|
"for example in examples:\n",
|
|
" tokens = encoding.encode(example)\n",
|
|
" print(f\" '{example:15s}' → {len(tokens):2d} token(s): {tokens}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "part3",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"# 🌍 Part 3: English vs French Token Efficiency\n",
|
|
"\n",
|
|
"<div style=\"background-color:rgb(174, 123, 41); padding: 20px; border-left: 5px solid #ff9800; border-radius: 5px;\">\n",
|
|
" <h3>🎯 Key Finding</h3>\n",
|
|
" <p><strong>English text typically requires fewer tokens than equivalent text in other languages!</strong></p>\n",
|
|
" <p>This is because the tokenizer was trained primarily on English text.</p>\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "why-language-matters",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🤔 Why Does This Matter?\n",
|
|
"\n",
|
|
"```\n",
|
|
"💰 Same meaning, different costs!\n",
|
|
"\n",
|
|
"English: \"Hello, how are you?\" → 6 tokens\n",
|
|
"French: \"Bonjour, comment allez-vous?\" → 8 tokens\n",
|
|
"\n",
|
|
"Cost impact: 33% more expensive in French! 💸\n",
|
|
"```\n",
|
|
"\n",
|
|
"### Real-World Implications:\n",
|
|
"\n",
|
|
"1. **💰 API Costs**: Non-English languages cost more per message\n",
|
|
"2. **📏 Context Windows**: Reach token limits faster\n",
|
|
"3. **⚡ Performance**: Longer processing times\n",
|
|
"4. **🎯 Optimization**: Need to be more careful with prompts\n",
|
|
"\n",
|
|
"---"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "comparison-experiment",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🧪 Experiment: Same Sentences, Different Languages\n",
|
|
"\n",
|
|
"Let's compare token usage across multiple equivalent sentences:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "language-comparison-1",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"🗣️ EXAMPLE 1: Simple Greeting\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 Token Count Comparison\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"English:\n",
|
|
" 📝 Text: Hello, how are you today?\n",
|
|
" 🔢 Tokens: 7\n",
|
|
" 📏 Characters: 25\n",
|
|
" 📊 Chars per token: 3.57\n",
|
|
"\n",
|
|
"French:\n",
|
|
" 📝 Text: Bonjour, comment allez-vous aujourd'hui?\n",
|
|
" 🔢 Tokens: 9\n",
|
|
" 📏 Characters: 40\n",
|
|
" 📊 Chars per token: 4.44\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 1: Simple greeting\n",
|
|
"sentences_1 = {\n",
|
|
" \"English\": \"Hello, how are you today?\",\n",
|
|
" \"French\": \"Bonjour, comment allez-vous aujourd'hui?\",\n",
|
|
"}\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"🗣️ EXAMPLE 1: Simple Greeting\")\n",
|
|
"results_1 = compare_texts(sentences_1)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "language-comparison-2",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"🗣️ EXAMPLE 2: Technical Description\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 Token Count Comparison\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"English:\n",
|
|
" 📝 Text: Machine learning is a subset of artificial intelligence that...\n",
|
|
" 🔢 Tokens: 16\n",
|
|
" 📏 Characters: 98\n",
|
|
" 📊 Chars per token: 6.12\n",
|
|
"\n",
|
|
"French:\n",
|
|
" 📝 Text: L'apprentissage automatique est un sous-ensemble de l'intell...\n",
|
|
" 🔢 Tokens: 35\n",
|
|
" 📏 Characters: 139\n",
|
|
" 📊 Chars per token: 3.97\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 2: Technical description\n",
|
|
"sentences_2 = {\n",
|
|
" \"English\": \"Machine learning is a subset of artificial intelligence that enables computers to learn from data.\",\n",
|
|
" \"French\": \"L'apprentissage automatique est un sous-ensemble de l'intelligence artificielle qui permet aux ordinateurs d'apprendre à partir de données.\",\n",
|
|
"}\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"🗣️ EXAMPLE 2: Technical Description\")\n",
|
|
"results_2 = compare_texts(sentences_2)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"id": "language-comparison-3",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"🗣️ EXAMPLE 3: Longer Paragraph\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 Token Count Comparison\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"English:\n",
|
|
" 📝 Text: The quick brown fox jumps over the lazy dog. This sentence c...\n",
|
|
" 🔢 Tokens: 28\n",
|
|
" 📏 Characters: 150\n",
|
|
" 📊 Chars per token: 5.36\n",
|
|
"\n",
|
|
"French:\n",
|
|
" 📝 Text: Le renard brun rapide saute par-dessus le chien paresseux. C...\n",
|
|
" 🔢 Tokens: 45\n",
|
|
" 📏 Characters: 176\n",
|
|
" 📊 Chars per token: 3.91\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Example 3: Longer paragraph\n",
|
|
"sentences_3 = {\n",
|
|
" \"English\": \"The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet and is commonly used for testing fonts and keyboards.\",\n",
|
|
" \"French\": \"Le renard brun rapide saute par-dessus le chien paresseux. Cette phrase contient chaque lettre de l'alphabet et est couramment utilisée pour tester les polices et les claviers.\",\n",
|
|
"}\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"🗣️ EXAMPLE 3: Longer Paragraph\")\n",
|
|
"results_3 = compare_texts(sentences_3)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "detailed-analysis",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 📊 Detailed Token Breakdown"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "detailed-english",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"🇬🇧 ENGLISH TOKENIZATION:\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: Hello, how are you today?\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 7\n",
|
|
"\n",
|
|
"Token 1: 9906 → 'Hello'\n",
|
|
"Token 2: 11 → ','\n",
|
|
"Token 3: 1268 → ' how'\n",
|
|
"Token 4: 527 → ' are'\n",
|
|
"Token 5: 499 → ' you'\n",
|
|
"Token 6: 3432 → ' today'\n",
|
|
"Token 7: 30 → '?'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Detailed breakdown - English\n",
|
|
"print(\"\\n🇬🇧 ENGLISH TOKENIZATION:\")\n",
|
|
"visualize_tokens(\"Hello, how are you today?\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"id": "detailed-french",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"🇫🇷 FRENCH TOKENIZATION:\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"Text: Bonjour, comment allez-vous aujourd'hui?\n",
|
|
"======================================================================\n",
|
|
"Total tokens: 9\n",
|
|
"\n",
|
|
"Token 1: 82681 → 'Bonjour'\n",
|
|
"Token 2: 11 → ','\n",
|
|
"Token 3: 4068 → ' comment'\n",
|
|
"Token 4: 12584 → ' alle'\n",
|
|
"Token 5: 89 → 'z'\n",
|
|
"Token 6: 45325 → '-vous'\n",
|
|
"Token 7: 75804 → ' aujourd'\n",
|
|
"Token 8: 88253 → ''hui'\n",
|
|
"Token 9: 30 → '?'\n",
|
|
"======================================================================\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Detailed breakdown - French\n",
|
|
"print(\"\\n🇫🇷 FRENCH TOKENIZATION:\")\n",
|
|
"visualize_tokens(\"Bonjour, comment allez-vous aujourd'hui?\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "visual-comparison",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 📈 Visual Comparison\n",
|
|
"\n",
|
|
"Let's create a bar chart to visualize the difference:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "create-chart",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56330/1860822118.py:87: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
|
|
" ax2.set_xticklabels(names, rotation=45, ha=\"right\")\n",
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56330/1860822118.py:103: UserWarning: Glyph 127468 (\\N{REGIONAL INDICATOR SYMBOL LETTER G}) missing from font(s) DejaVu Sans.\n",
|
|
" plt.tight_layout()\n",
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56330/1860822118.py:103: UserWarning: Glyph 127463 (\\N{REGIONAL INDICATOR SYMBOL LETTER B}) missing from font(s) DejaVu Sans.\n",
|
|
" plt.tight_layout()\n",
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56330/1860822118.py:103: UserWarning: Glyph 127467 (\\N{REGIONAL INDICATOR SYMBOL LETTER F}) missing from font(s) DejaVu Sans.\n",
|
|
" plt.tight_layout()\n",
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56330/1860822118.py:103: UserWarning: Glyph 127479 (\\N{REGIONAL INDICATOR SYMBOL LETTER R}) missing from font(s) DejaVu Sans.\n",
|
|
" plt.tight_layout()\n",
|
|
"/Users/arthurdanjou/Workspace/studies/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 127468 (\\N{REGIONAL INDICATOR SYMBOL LETTER G}) missing from font(s) DejaVu Sans.\n",
|
|
" fig.canvas.print_figure(bytes_io, **kw)\n",
|
|
"/Users/arthurdanjou/Workspace/studies/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 127463 (\\N{REGIONAL INDICATOR SYMBOL LETTER B}) missing from font(s) DejaVu Sans.\n",
|
|
" fig.canvas.print_figure(bytes_io, **kw)\n",
|
|
"/Users/arthurdanjou/Workspace/studies/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 127467 (\\N{REGIONAL INDICATOR SYMBOL LETTER F}) missing from font(s) DejaVu Sans.\n",
|
|
" fig.canvas.print_figure(bytes_io, **kw)\n",
|
|
"/Users/arthurdanjou/Workspace/studies/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 127479 (\\N{REGIONAL INDICATOR SYMBOL LETTER R}) missing from font(s) DejaVu Sans.\n",
|
|
" fig.canvas.print_figure(bytes_io, **kw)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAABjUAAAJOCAYAAAD/KYUYAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAA1SZJREFUeJzs3QeYE9X38PHD0stSpauAdEF6FRGQIghIERVsVJVmoaiAKL0oVYqFIk2lKEWUJl2QIk1AegfpvffN+5z7+0/eJJtdskt2s7P5fp5nniQzk2QymZ2dm3PPuQlExCEAAAAAAAAAAABxXEigNwAAAAAAAAAAAMAXBDUAAAAAAAAAAIAtENQAAAAAAAAAAAC2QFADAAAAAAAAAADYAkENAAAAAAAAAABgCwQ1AAAAAAAAAACALRDUAAAAAAAAAAAAtkBQAwAAAAAAAAAA2AJBDQAAAAAAAAAAYAsENYAYliNHDnE4HM6pUqVK7HPAC/3bcP1b0b8dxN3vZMKECc75y5cvj/Z79OjRw/k6hw4d8tOWI7Y0bdrU7RgBAAD2oNdd1v9vvR6zA9drDr0GQWDYvd3mr3YMgMAiqIGg5noh5+sUrEGJp59+Wr777jvZvn27XLx4Ue7cuSNnz56VP//8U3r27ClPPPGE2I1ewFjfq17YRFfChAnl1VdflenTp8uBAwfk6tWrcvv2bTl27Jj8/vvv0q5dO0mbNq1ftx3xL+AZ0cSFtn3PK5FNdmv8AQAQTD/SRjQ9TJshPvP1+oeghEjt2rXlp59+Mu3Ga9euyY0bN+TIkSMya9Ysady4sYSE8DMdAPgikU9rAQha+mP8999/Lw0aNAi37JFHHpGKFSuaSRsCVapUkWBTqFAhE8zQW0+PPvqomfTCVfdVr169ArKNdqEX9p07d3Y+vnDhQkC3B5GbNm2a/Pvvv+a+BvAAAAAAeJcxY0Zz/fzcc8+FW/b444+bSdvcH3/8sbz00ktkMAPAAxDUQFDr16+fpEmTxvk4Xbp08umnnzof//HHH2by/OE1WKRIkcJ8/tKlSzvnnTx5UubMmSNHjx6V0NBQKVGihFStWlWCUf78+WXlypWSIUMG5zzNZFm4cKH5QT5Tpkwm4FOqVKmAbqcdjrObN2/Kf//9J0OGDJFg5e18E5cDBosWLTITIqbngf79+0e4zNe/Dco6AQAQu/TH540bN4abb3XoeBBtJ2n2drD45ptvTIa6q8GDBzvvb9iwwXQEc6XzgkWyZMlkwYIFUrJkSee8LVu2yLx58+Tu3bumPf3ss8+a+cWLF5elS5eaNvj58+clLrGuTQEgrtACyEzsA44BEUeOHDkcrnr06BFuv4SEhDiaN2/uWLJkiePs2bOOO3fuOM6dO+dYtmyZo1WrVo6ECRNG+pqVKlVyLnvppZccd+/edS4bN26cI0GCBGZZkiRJHO3atXOsXLnScf78ecft27cdJ06ccMyYMcNRrly5cNvVtGlTt/fR53fr1s2xZ88ex61btxzHjh1zDBo0yMz39Xjv37+/22vOnj3bkTx58nDrZc2a1fHOO++Em//cc885fv75Z/Peug2XL192bNq0ydGzZ09HunTpwq3vSj+P67IJEyY4ly1fvjzS51WrVs18H1evXnVcuXLFMX/+fMeTTz7pXF+/1wfR7+1B++evv/5ye06XLl28rleiRAlH3bp1/XocValSxfH+++87du/e7bhx44Zj+/btjtdff92smyJFCseQIUMc//33n+PmzZuOzZs3O+rVqxduuw4dOuR2rJcpU8axaNEix6VLl8x+W7hwodl2z+fpdk+fPt2xc+dO57brd7tlyxbHwIEDHRkyZHjge1WoUMGxePFi814qTZo05m8jou9AP9Nnn31mjh/dNn3P06dPm/ccM2aM4/nnnw/3nnnz5nV8/fXXZh9dv37dTPr38O233zry588fbn3PYyxLliyO7777zvzd6fGrn1e/G8/neW6369/4w55vvE1RPd5dp5YtWzq2bdtmjoujR4+ac4LuW8/vJ6LP5vqdRPY3WbhwYceUKVPM6+q+02P0yJEjjqVLl5rzSrZs2bz+Per6uj39+vVzHDx40Dz3wIEDjq5du/q0b0JDQx3Xrl1z2z+e60ybNs25/I8//nDOf+aZZxyzZs0yfzd6vtX9qduj+1O3MXXq1D5tg+4L18/zoPV9+duw1i1SpIhj/Pjxjv3795t9qtuof9+6f3S/Pei19e/5t99+c1y8eNH8Pfz555/m/bxtV/r06R3du3d3rF271nHhwgXzXei+0fPCK6+8EuH/nkSJEjk++ugjx65du6L9v4eJfcAxwDHAMcAxENvHgOc1j7drCNfJ8/+ftpH69u1rrlv0OnXYsGHOdWO7XVe1alVzvXP48GFzzafX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O3fumMnT/fv3zQQAiAPC7H0+5v8JEMdwTokz57StW7dK6dKl5ccffzTX+gAAAADgKkRsLHv27JIhQwY5efKk1+V3796VTZs2SdWqVZ3zNJVdH69duzYWtxQAAACAL7p06WKCJC1btjSlZAEAAADAVZxqJaRMmdJkXVhy5colRYsWNQOB69SjRw+ZOXOmybLQMTW+/PJL2b9/vyxatMj5HB0EfPbs2TJ69GjzWMtITZo0STZu3Ch///23fPjhh+Z9JkyYEJDPCAAAAOD/Gz9+fLjdcfjwYalfv74cPXpU1q1bJxcvXnRbruWpWrVqxW4EAAAAglCcCmqUKlVKVqxY4Xw8bNgwcztx4kRp06aNFClSRJo2bSpp06aVEydOyB9//CGfffaZW6koDXboAOGWGTNmSMaMGaV3796SJUsW+eeff6RmzZpy5syZWP50AAAAADw1a9bMBCm80bKxL774otdlBDUAAACA4BSnghorV6405aEiosGIB9HsDk+atWFlbgAAAACIWyJrA3hbFlEQBAAAAED8F6eCGgAAAACCS5UqVQK9CQAAAABshKAGAAAAgID5888/2fsAAAAAfEZQAwAAAECc8eijj5qSsmFhYfLXX3+5LatQoYKEhITIoUOH5L///gvYNgIAAAAInJAAvjcAAAAAuBk6dKgsX75c2rdvH27PtG7d2iwbMmQIew0AAAAIUgQ1AMQ7jRs3lvXr18utW7fMQKL644c3zZs3N8t1mjp1aqxvJwAACK98+fLmdtasWeGW/frrr2bgcGsdAAAAAMGHoAaAeKdIkSKmZMXevXsjXCd//vwycuRIuXv3bqxuGwAAiFzGjBnN7bVr18Itu379uts6AAAAAIIPQQ0A8U63bt1MD8558+Z5XZ4kSRKZNm2a7Nu3T3755ZdY3z4AABCxy5cvm9t69eqFW2bNu3LlCrsQAAAACFIMFA4g6Ggd7ty5c0vJkiVNAAQAAMQdGzZskFq1akmrVq0kRYoUzk4KtWvXltdff92UjdR1AAAAAAQnghoAgor28NSBR9966y2TqQEAAOIWLQ+pQQ312muvmcnbOgAAAACCE+WnAASVpk2bys2bN+WVV16R3377TapWrWrmV6xYUcaNGxfozQMAIOgtWrRIevbsaQYE95xU7969zToAAAAAghOZGgCCiv4gkjx5cqlTp47b/OzZszsD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",
|
|
"text/plain": [
|
|
"<Figure size 1600x600 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 SUMMARY STATISTICS\n",
|
|
"======================================================================\n",
|
|
"Average English tokens: 8.0\n",
|
|
"Average French tokens: 13.0\n",
|
|
"Average increase: 64.3%\n",
|
|
"\n",
|
|
"💡 On average, French uses 64.3% more tokens than English!\n",
|
|
"======================================================================\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Prepare data for comprehensive comparison\n",
|
|
"test_cases = [\n",
|
|
" {\n",
|
|
" \"name\": \"Greeting\",\n",
|
|
" \"en\": \"Hello, how are you?\",\n",
|
|
" \"fr\": \"Bonjour, comment allez-vous?\",\n",
|
|
" },\n",
|
|
" {\n",
|
|
" \"name\": \"Introduction\",\n",
|
|
" \"en\": \"My name is John and I live in New York.\",\n",
|
|
" \"fr\": \"Je m'appelle Jean et j'habite à New York.\",\n",
|
|
" },\n",
|
|
" {\n",
|
|
" \"name\": \"Technical\",\n",
|
|
" \"en\": \"Machine learning algorithms process large datasets.\",\n",
|
|
" \"fr\": \"Les algorithmes d'apprentissage automatique traitent de grands ensembles de données.\",\n",
|
|
" },\n",
|
|
" {\n",
|
|
" \"name\": \"Question\",\n",
|
|
" \"en\": \"What time does the store close?\",\n",
|
|
" \"fr\": \"À quelle heure ferme le magasin?\",\n",
|
|
" },\n",
|
|
" {\n",
|
|
" \"name\": \"Instruction\",\n",
|
|
" \"en\": \"Please send me the report by tomorrow morning.\",\n",
|
|
" \"fr\": \"Veuillez m'envoyer le rapport d'ici demain matin.\",\n",
|
|
" },\n",
|
|
"]\n",
|
|
"\n",
|
|
"# Calculate tokens for each\n",
|
|
"names = []\n",
|
|
"en_tokens = []\n",
|
|
"fr_tokens = []\n",
|
|
"differences = []\n",
|
|
"\n",
|
|
"for case in test_cases:\n",
|
|
" names.append(case[\"name\"])\n",
|
|
" en_count = count_tokens(case[\"en\"])\n",
|
|
" fr_count = count_tokens(case[\"fr\"])\n",
|
|
" en_tokens.append(en_count)\n",
|
|
" fr_tokens.append(fr_count)\n",
|
|
" differences.append(fr_count - en_count)\n",
|
|
"\n",
|
|
"# Create the visualization\n",
|
|
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))\n",
|
|
"\n",
|
|
"# Left chart: Token comparison\n",
|
|
"x = np.arange(len(names))\n",
|
|
"width = 0.35\n",
|
|
"\n",
|
|
"bars1 = ax1.bar(x - width / 2, en_tokens, width, label=\"English 🇬🇧\", color=\"#4285f4\")\n",
|
|
"bars2 = ax1.bar(x + width / 2, fr_tokens, width, label=\"French 🇫🇷\", color=\"#ea4335\")\n",
|
|
"\n",
|
|
"ax1.set_xlabel(\"Sentence Type\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax1.set_ylabel(\"Number of Tokens\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax1.set_title(\n",
|
|
" \"Token Count Comparison: English vs French\",\n",
|
|
" fontsize=14,\n",
|
|
" fontweight=\"bold\",\n",
|
|
")\n",
|
|
"ax1.set_xticks(x)\n",
|
|
"ax1.set_xticklabels(names, rotation=45, ha=\"right\")\n",
|
|
"ax1.legend()\n",
|
|
"ax1.grid(axis=\"y\", alpha=0.3)\n",
|
|
"\n",
|
|
"# Add value labels on bars\n",
|
|
"for bars in [bars1, bars2]:\n",
|
|
" for bar in bars:\n",
|
|
" height = bar.get_height()\n",
|
|
" ax1.text(\n",
|
|
" bar.get_x() + bar.get_width() / 2.0,\n",
|
|
" height,\n",
|
|
" f\"{int(height)}\",\n",
|
|
" ha=\"center\",\n",
|
|
" va=\"bottom\",\n",
|
|
" fontsize=9,\n",
|
|
" fontweight=\"bold\",\n",
|
|
" )\n",
|
|
"\n",
|
|
"# Right chart: Percentage increase\n",
|
|
"percentage_increase = [\n",
|
|
" (fr - en) / en * 100 for en, fr in zip(en_tokens, fr_tokens, strict=False)\n",
|
|
"]\n",
|
|
"colors = [\"#ea4335\" if x > 0 else \"#34a853\" for x in percentage_increase]\n",
|
|
"\n",
|
|
"bars3 = ax2.bar(names, percentage_increase, color=colors, alpha=0.7)\n",
|
|
"ax2.axhline(y=0, color=\"black\", linestyle=\"-\", linewidth=0.5)\n",
|
|
"ax2.set_xlabel(\"Sentence Type\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax2.set_ylabel(\"% More Tokens in French\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax2.set_title(\"French Token Overhead\", fontsize=14, fontweight=\"bold\")\n",
|
|
"ax2.set_xticklabels(names, rotation=45, ha=\"right\")\n",
|
|
"ax2.grid(axis=\"y\", alpha=0.3)\n",
|
|
"\n",
|
|
"# Add value labels\n",
|
|
"for bar, val in zip(bars3, percentage_increase, strict=False):\n",
|
|
" height = bar.get_height()\n",
|
|
" ax2.text(\n",
|
|
" bar.get_x() + bar.get_width() / 2.0,\n",
|
|
" height,\n",
|
|
" f\"{val:+.1f}%\",\n",
|
|
" ha=\"center\",\n",
|
|
" va=\"bottom\" if height > 0 else \"top\",\n",
|
|
" fontsize=9,\n",
|
|
" fontweight=\"bold\",\n",
|
|
" )\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()\n",
|
|
"\n",
|
|
"# Print summary statistics\n",
|
|
"avg_en = np.mean(en_tokens)\n",
|
|
"avg_fr = np.mean(fr_tokens)\n",
|
|
"avg_increase = np.mean(percentage_increase)\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"📊 SUMMARY STATISTICS\")\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(f\"Average English tokens: {avg_en:.1f}\")\n",
|
|
"print(f\"Average French tokens: {avg_fr:.1f}\")\n",
|
|
"print(f\"Average increase: {avg_increase:.1f}%\")\n",
|
|
"print(f\"\\n💡 On average, French uses {avg_increase:.1f}% more tokens than English!\")\n",
|
|
"print(\"=\" * 70)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "part4",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"# 📦 Part 4: JSON vs YAML Token Efficiency\n",
|
|
"\n",
|
|
"<div style=\"background-color:rgb(19, 172, 32); padding: 20px; border-left: 5px solid #4caf50; border-radius: 5px;\">\n",
|
|
" <h3>🎯 Key Finding</h3>\n",
|
|
" <p><strong>YAML typically uses fewer tokens than JSON for the same data!</strong></p>\n",
|
|
" <p>This is because YAML has less syntactic overhead (fewer brackets, quotes, and commas).</p>\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "why-format-matters",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🤔 Why Does Data Format Matter?\n",
|
|
"\n",
|
|
"When working with LLMs, you often need to:\n",
|
|
"- Send structured data in prompts\n",
|
|
"- Receive structured responses\n",
|
|
"- Store conversation context\n",
|
|
"\n",
|
|
"### Format Characteristics:\n",
|
|
"\n",
|
|
"```json\n",
|
|
"// JSON: More verbose ❌\n",
|
|
"{\n",
|
|
" \"name\": \"Alice\",\n",
|
|
" \"age\": 30,\n",
|
|
" \"city\": \"Paris\"\n",
|
|
"}\n",
|
|
"```\n",
|
|
"\n",
|
|
"```yaml\n",
|
|
"# YAML: More concise ✅\n",
|
|
"name: Alice\n",
|
|
"age: 30\n",
|
|
"city: Paris\n",
|
|
"```\n",
|
|
"\n",
|
|
"### Token Efficiency Benefits:\n",
|
|
"\n",
|
|
"1. **💰 Lower Costs**: Fewer tokens = less expensive\n",
|
|
"2. **📏 More Context**: Fit more data in token limits\n",
|
|
"3. **⚡ Faster**: Less data to process\n",
|
|
"4. **👁️ Readability**: Still human-readable\n",
|
|
"\n",
|
|
"---"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "format-comparison",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🧪 Experiment: Same Data, Different Formats"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"id": "create-sample-data",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Sample data structure created! ✅\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Create sample data structure\n",
|
|
"sample_data = {\n",
|
|
" \"user\": {\n",
|
|
" \"name\": \"Alice Johnson\",\n",
|
|
" \"email\": \"alice@example.com\",\n",
|
|
" \"age\": 30,\n",
|
|
" \"active\": True,\n",
|
|
" },\n",
|
|
" \"preferences\": {\"theme\": \"dark\", \"language\": \"en\", \"notifications\": True},\n",
|
|
" \"settings\": [\"auto_save\", \"sync_enabled\", \"backup_daily\"],\n",
|
|
"}\n",
|
|
"\n",
|
|
"# Convert to JSON\n",
|
|
"json_string = json.dumps(sample_data, indent=2)\n",
|
|
"\n",
|
|
"# Convert to YAML\n",
|
|
"yaml_string = yaml.dump(sample_data, default_flow_style=False, sort_keys=False)\n",
|
|
"\n",
|
|
"print(\"Sample data structure created! ✅\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"id": "show-json",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"📄 JSON VERSION:\n",
|
|
"======================================================================\n",
|
|
"{\n",
|
|
" \"user\": {\n",
|
|
" \"name\": \"Alice Johnson\",\n",
|
|
" \"email\": \"alice@example.com\",\n",
|
|
" \"age\": 30,\n",
|
|
" \"active\": true\n",
|
|
" },\n",
|
|
" \"preferences\": {\n",
|
|
" \"theme\": \"dark\",\n",
|
|
" \"language\": \"en\",\n",
|
|
" \"notifications\": true\n",
|
|
" },\n",
|
|
" \"settings\": [\n",
|
|
" \"auto_save\",\n",
|
|
" \"sync_enabled\",\n",
|
|
" \"backup_daily\"\n",
|
|
" ]\n",
|
|
"}\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"📊 Statistics:\n",
|
|
" Characters: 286\n",
|
|
" Tokens: 88\n",
|
|
" Lines: 18\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Display JSON version\n",
|
|
"print(\"📄 JSON VERSION:\")\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(json_string)\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(\"\\n📊 Statistics:\")\n",
|
|
"print(f\" Characters: {len(json_string)}\")\n",
|
|
"print(f\" Tokens: {count_tokens(json_string)}\")\n",
|
|
"print(f\" Lines: {json_string.count(chr(10)) + 1}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"id": "show-yaml",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"📄 YAML VERSION:\n",
|
|
"======================================================================\n",
|
|
"user:\n",
|
|
" name: Alice Johnson\n",
|
|
" email: alice@example.com\n",
|
|
" age: 30\n",
|
|
" active: true\n",
|
|
"preferences:\n",
|
|
" theme: dark\n",
|
|
" language: en\n",
|
|
" notifications: true\n",
|
|
"settings:\n",
|
|
"- auto_save\n",
|
|
"- sync_enabled\n",
|
|
"- backup_daily\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"📊 Statistics:\n",
|
|
" Characters: 196\n",
|
|
" Tokens: 57\n",
|
|
" Lines: 14\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Display YAML version\n",
|
|
"print(\"📄 YAML VERSION:\")\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(yaml_string)\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(\"\\n📊 Statistics:\")\n",
|
|
"print(f\" Characters: {len(yaml_string)}\")\n",
|
|
"print(f\" Tokens: {count_tokens(yaml_string)}\")\n",
|
|
"print(f\" Lines: {yaml_string.count(chr(10)) + 1}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"id": "format-comparison-detailed",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 COMPARISON SUMMARY\n",
|
|
"======================================================================\n",
|
|
"\n",
|
|
"📄 Format Comparison:\n",
|
|
" JSON: 88 tokens\n",
|
|
" YAML: 57 tokens\n",
|
|
"\n",
|
|
"💾 Savings:\n",
|
|
" Token reduction: 31 tokens\n",
|
|
" Percentage saved: 35.2%\n",
|
|
"\n",
|
|
"✨ YAML is 35.2% more token-efficient than JSON!\n",
|
|
"======================================================================\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Detailed comparison\n",
|
|
"json_tokens = count_tokens(json_string)\n",
|
|
"yaml_tokens = count_tokens(yaml_string)\n",
|
|
"token_savings = json_tokens - yaml_tokens\n",
|
|
"percentage_savings = (token_savings / json_tokens) * 100\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"📊 COMPARISON SUMMARY\")\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(\"\\n📄 Format Comparison:\")\n",
|
|
"print(f\" JSON: {json_tokens} tokens\")\n",
|
|
"print(f\" YAML: {yaml_tokens} tokens\")\n",
|
|
"print(\"\\n💾 Savings:\")\n",
|
|
"print(f\" Token reduction: {token_savings} tokens\")\n",
|
|
"print(f\" Percentage saved: {percentage_savings:.1f}%\")\n",
|
|
"print(f\"\\n✨ YAML is {percentage_savings:.1f}% more token-efficient than JSON!\")\n",
|
|
"print(\"=\" * 70)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "multiple-examples",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 📊 Comprehensive Format Comparison\n",
|
|
"\n",
|
|
"Let's test with different data structures:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"id": "comprehensive-comparison",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📋 User Profile\n",
|
|
"======================================================================\n",
|
|
"JSON: 64 tokens\n",
|
|
"YAML: 42 tokens\n",
|
|
"💾 Saved: 22 tokens (34.4%)\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📋 Configuration\n",
|
|
"======================================================================\n",
|
|
"JSON: 91 tokens\n",
|
|
"YAML: 62 tokens\n",
|
|
"💾 Saved: 29 tokens (31.9%)\n",
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📋 API Response\n",
|
|
"======================================================================\n",
|
|
"JSON: 159 tokens\n",
|
|
"YAML: 115 tokens\n",
|
|
"💾 Saved: 44 tokens (27.7%)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Test Case 1: User profile\n",
|
|
"user_profile = {\n",
|
|
" \"id\": \"12345\",\n",
|
|
" \"username\": \"alice_wonder\",\n",
|
|
" \"email\": \"alice@example.com\",\n",
|
|
" \"created_at\": \"2024-01-15\",\n",
|
|
" \"is_verified\": True,\n",
|
|
" \"roles\": [\"user\", \"moderator\"],\n",
|
|
"}\n",
|
|
"\n",
|
|
"# Test Case 2: Configuration file\n",
|
|
"config = {\n",
|
|
" \"database\": {\n",
|
|
" \"host\": \"localhost\",\n",
|
|
" \"port\": 5432,\n",
|
|
" \"name\": \"myapp_db\",\n",
|
|
" \"pool_size\": 10,\n",
|
|
" },\n",
|
|
" \"cache\": {\n",
|
|
" \"enabled\": True,\n",
|
|
" \"ttl\": 3600,\n",
|
|
" \"max_size\": 1000,\n",
|
|
" },\n",
|
|
" \"features\": [\"analytics\", \"notifications\", \"dark_mode\"],\n",
|
|
"}\n",
|
|
"\n",
|
|
"# Test Case 3: API response\n",
|
|
"api_response = {\n",
|
|
" \"status\": \"success\",\n",
|
|
" \"data\": {\n",
|
|
" \"items\": [\n",
|
|
" {\"id\": 1, \"name\": \"Item 1\", \"price\": 29.99},\n",
|
|
" {\"id\": 2, \"name\": \"Item 2\", \"price\": 49.99},\n",
|
|
" {\"id\": 3, \"name\": \"Item 3\", \"price\": 19.99},\n",
|
|
" ],\n",
|
|
" \"total\": 3,\n",
|
|
" \"page\": 1,\n",
|
|
" },\n",
|
|
" \"meta\": {\"timestamp\": \"2024-12-11T10:30:00Z\", \"version\": \"2.0\"},\n",
|
|
"}\n",
|
|
"\n",
|
|
"test_cases = [\n",
|
|
" (\"User Profile\", user_profile),\n",
|
|
" (\"Configuration\", config),\n",
|
|
" (\"API Response\", api_response),\n",
|
|
"]\n",
|
|
"\n",
|
|
"# Analyze each case\n",
|
|
"results = []\n",
|
|
"\n",
|
|
"for name, data in test_cases:\n",
|
|
" json_str = json.dumps(data, indent=2)\n",
|
|
" yaml_str = yaml.dump(data, default_flow_style=False)\n",
|
|
"\n",
|
|
" json_tokens = count_tokens(json_str)\n",
|
|
" yaml_tokens = count_tokens(yaml_str)\n",
|
|
" savings = json_tokens - yaml_tokens\n",
|
|
" savings_pct = (savings / json_tokens) * 100\n",
|
|
"\n",
|
|
" results.append(\n",
|
|
" {\n",
|
|
" \"name\": name,\n",
|
|
" \"json\": json_tokens,\n",
|
|
" \"yaml\": yaml_tokens,\n",
|
|
" \"savings\": savings,\n",
|
|
" \"savings_pct\": savings_pct,\n",
|
|
" },\n",
|
|
" )\n",
|
|
"\n",
|
|
" print(f\"\\n{'=' * 70}\")\n",
|
|
" print(f\"📋 {name}\")\n",
|
|
" print(f\"{'=' * 70}\")\n",
|
|
" print(f\"JSON: {json_tokens} tokens\")\n",
|
|
" print(f\"YAML: {yaml_tokens} tokens\")\n",
|
|
" print(f\"💾 Saved: {savings} tokens ({savings_pct:.1f}%)\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "visual-format-comparison",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 📈 Visual Comparison: JSON vs YAML"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"id": "format-visualization",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/var/folders/tp/_ld5_pzs6nx6mv1pbjhq1l740000gn/T/ipykernel_56237/3781130823.py:44: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n",
|
|
" ax2.set_xticklabels(names, rotation=45, ha=\"right\")\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 1600x600 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"======================================================================\n",
|
|
"📊 OVERALL SUMMARY\n",
|
|
"======================================================================\n",
|
|
"Total JSON tokens: 314\n",
|
|
"Total YAML tokens: 219\n",
|
|
"Total tokens saved: 95\n",
|
|
"Average savings: 31.3%\n",
|
|
"\n",
|
|
"💡 YAML saves an average of 31.3% tokens compared to JSON!\n",
|
|
"======================================================================\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Create visualization\n",
|
|
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))\n",
|
|
"\n",
|
|
"# Extract data\n",
|
|
"names = [r[\"name\"] for r in results]\n",
|
|
"json_tokens = [r[\"json\"] for r in results]\n",
|
|
"yaml_tokens = [r[\"yaml\"] for r in results]\n",
|
|
"savings_pct = [r[\"savings_pct\"] for r in results]\n",
|
|
"\n",
|
|
"# Left chart: Token comparison\n",
|
|
"x = np.arange(len(names))\n",
|
|
"width = 0.35\n",
|
|
"\n",
|
|
"bars1 = ax1.bar(x - width / 2, json_tokens, width, label=\"JSON\", color=\"#f39c12\")\n",
|
|
"bars2 = ax1.bar(x + width / 2, yaml_tokens, width, label=\"YAML\", color=\"#27ae60\")\n",
|
|
"\n",
|
|
"ax1.set_xlabel(\"Data Structure Type\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax1.set_ylabel(\"Number of Tokens\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax1.set_title(\"Token Count: JSON vs YAML\", fontsize=14, fontweight=\"bold\")\n",
|
|
"ax1.set_xticks(x)\n",
|
|
"ax1.set_xticklabels(names, rotation=45, ha=\"right\")\n",
|
|
"ax1.legend()\n",
|
|
"ax1.grid(axis=\"y\", alpha=0.3)\n",
|
|
"\n",
|
|
"# Add value labels\n",
|
|
"for bars in [bars1, bars2]:\n",
|
|
" for bar in bars:\n",
|
|
" height = bar.get_height()\n",
|
|
" ax1.text(\n",
|
|
" bar.get_x() + bar.get_width() / 2.0,\n",
|
|
" height,\n",
|
|
" f\"{int(height)}\",\n",
|
|
" ha=\"center\",\n",
|
|
" va=\"bottom\",\n",
|
|
" fontsize=10,\n",
|
|
" fontweight=\"bold\",\n",
|
|
" )\n",
|
|
"\n",
|
|
"# Right chart: Savings percentage\n",
|
|
"bars3 = ax2.bar(names, savings_pct, color=\"#27ae60\", alpha=0.7)\n",
|
|
"ax2.set_xlabel(\"Data Structure Type\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax2.set_ylabel(\"Token Savings (%)\", fontsize=12, fontweight=\"bold\")\n",
|
|
"ax2.set_title(\"YAML Token Savings vs JSON\", fontsize=14, fontweight=\"bold\")\n",
|
|
"ax2.set_xticklabels(names, rotation=45, ha=\"right\")\n",
|
|
"ax2.grid(axis=\"y\", alpha=0.3)\n",
|
|
"\n",
|
|
"# Add value labels\n",
|
|
"for bar, val in zip(bars3, savings_pct, strict=False):\n",
|
|
" height = bar.get_height()\n",
|
|
" ax2.text(\n",
|
|
" bar.get_x() + bar.get_width() / 2.0,\n",
|
|
" height,\n",
|
|
" f\"{val:.1f}%\",\n",
|
|
" ha=\"center\",\n",
|
|
" va=\"bottom\",\n",
|
|
" fontsize=10,\n",
|
|
" fontweight=\"bold\",\n",
|
|
" )\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()\n",
|
|
"\n",
|
|
"# Print summary\n",
|
|
"avg_savings_pct = np.mean(savings_pct)\n",
|
|
"total_json = sum(json_tokens)\n",
|
|
"total_yaml = sum(yaml_tokens)\n",
|
|
"total_savings = total_json - total_yaml\n",
|
|
"\n",
|
|
"print(\"\\n\" + \"=\" * 70)\n",
|
|
"print(\"📊 OVERALL SUMMARY\")\n",
|
|
"print(\"=\" * 70)\n",
|
|
"print(f\"Total JSON tokens: {total_json}\")\n",
|
|
"print(f\"Total YAML tokens: {total_yaml}\")\n",
|
|
"print(f\"Total tokens saved: {total_savings}\")\n",
|
|
"print(f\"Average savings: {avg_savings_pct:.1f}%\")\n",
|
|
"print(f\"\\n💡 YAML saves an average of {avg_savings_pct:.1f}% tokens compared to JSON!\")\n",
|
|
"print(\"=\" * 70)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "best-practices",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"# 💡 Best Practices & Key Takeaways\n",
|
|
"\n",
|
|
"## 🎯 Optimization Strategies\n",
|
|
"\n",
|
|
"### 1. Language Selection 🌍\n",
|
|
"\n",
|
|
"```\n",
|
|
"✅ DO:\n",
|
|
"- Use English when possible (most token-efficient)\n",
|
|
"- Consider token costs when supporting multiple languages\n",
|
|
"- Test your prompts in different languages to compare costs but also accuracy!\n",
|
|
"\n",
|
|
"⚠️ CONSIDER:\n",
|
|
"- User experience vs cost trade-offs\n",
|
|
"- Cultural appropriateness of language choice\n",
|
|
"- Whether translation adds value\n",
|
|
"```\n",
|
|
"\n",
|
|
"### 2. Data Format Choice 📦\n",
|
|
"\n",
|
|
"```\n",
|
|
"✅ Use YAML when:\n",
|
|
"- Sending structured data to LLMs\n",
|
|
"- Working within tight token limits\n",
|
|
"- Optimizing for cost\n",
|
|
"- Human readability matters\n",
|
|
"\n",
|
|
"✅ Use JSON when:\n",
|
|
"- Strict parsing requirements\n",
|
|
"- Working with existing JSON APIs\n",
|
|
"- Need for widespread tool support\n",
|
|
"- Compliance/standard requirements\n",
|
|
"```\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 📊 Quick Reference: Token Efficiency\n",
|
|
"\n",
|
|
"### Language Efficiency (1.0 = baseline)\n",
|
|
"```\n",
|
|
"English: 1.0x ⭐ Most efficient\n",
|
|
"Spanish: 1.2x\n",
|
|
"French: 1.3x\n",
|
|
"German: 1.4x\n",
|
|
"Japanese: 2.0x\n",
|
|
"Chinese: 2.5x ⚠️ Least efficient\n",
|
|
"```\n",
|
|
"\n",
|
|
"### Format Efficiency\n",
|
|
"```\n",
|
|
"YAML: 1.0x ⭐ Most efficient\n",
|
|
"JSON: 1.2x\n",
|
|
"XML: 1.5x ⚠️ Least efficient\n",
|
|
"```\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 🎓 Key Learnings\n",
|
|
"\n",
|
|
"<div style=\"background-color:rgb(223, 194, 96); padding: 20px; border-left: 5px solid #ffc107; border-radius: 5px; margin: 20px 0; color: black;\">\n",
|
|
" <h3>💡 Remember:</h3>\n",
|
|
" <ol>\n",
|
|
" <li><strong>Tokens ≠ Words:</strong> Tokenization is subword-level</li>\n",
|
|
" <li><strong>Language Matters:</strong> English is 20-50% more token-efficient</li>\n",
|
|
" <li><strong>Format Matters:</strong> YAML saves 15-30% vs JSON</li>\n",
|
|
" <li><strong>Spaces Count:</strong> Leading spaces affect tokenization</li>\n",
|
|
" <li><strong>Cost Impact:</strong> Small optimizations = big savings at scale</li>\n",
|
|
" </ol>\n",
|
|
"</div>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 🛠️ Practical Tools\n",
|
|
"\n",
|
|
"### For Your Projects:\n",
|
|
"\n",
|
|
"1. **Token Counter Function:**\n",
|
|
" ```python\n",
|
|
" def count_tokens(text):\n",
|
|
" encoding = tiktoken.get_encoding(\"cl100k_base\")\n",
|
|
" return len(encoding.encode(text))\n",
|
|
" ```\n",
|
|
"\n",
|
|
"2. **Cost Calculator:**\n",
|
|
" ```python\n",
|
|
" def calculate_cost(text, cost_per_1k=0.03):\n",
|
|
" tokens = count_tokens(text)\n",
|
|
" return (tokens / 1000) * cost_per_1k\n",
|
|
" ```\n",
|
|
"\n",
|
|
"3. **Format Optimizer:**\n",
|
|
" ```python\n",
|
|
" def optimize_format(data):\n",
|
|
" yaml_str = yaml.dump(data)\n",
|
|
" json_str = json.dumps(data)\n",
|
|
" return yaml_str if count_tokens(yaml_str) < count_tokens(json_str) else json_str\n",
|
|
" ```\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 📚 Additional Resources\n",
|
|
"\n",
|
|
"- 📖 [TikToken Documentation](https://github.com/openai/tiktoken)\n",
|
|
"- 🎯 [OpenAI Tokenizer Tool](https://platform.openai.com/tokenizer)\n",
|
|
"- 💰 [OpenAI Pricing Calculator](https://openai.com/pricing)\n",
|
|
"- 📊 [Token Optimization Guide](https://help.openai.com/en/articles/4936856)\n",
|
|
"\n",
|
|
"---"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2c0a69d4",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 📚 Exercise Set 1: Token Analysis Fundamentals"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"id": "e6cc9f9e",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Text: Hello, world!\n",
|
|
"Tokens: 4\n",
|
|
"Chars per token: 3.25\n",
|
|
"\n",
|
|
"Text: The quick brown fox jumps over the lazy dog.\n",
|
|
"Tokens: 10\n",
|
|
"Chars per token: 4.40\n",
|
|
"\n",
|
|
"Text: Machine learning and artificial intelligence are transforming technology.\n",
|
|
"Tokens: 9\n",
|
|
"Chars per token: 8.11\n",
|
|
"\n",
|
|
"Text: café résumé naïve\n",
|
|
"Tokens: 7\n",
|
|
"Chars per token: 2.43\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def analyze_tokenization(text: str) -> dict:\n",
|
|
" \"\"\"Analyze a text and return detailed tokenization statistics.\n",
|
|
"\n",
|
|
" Args:\n",
|
|
" text: Input text to analyze\n",
|
|
"\n",
|
|
" Returns:\n",
|
|
" Dictionary with keys:\n",
|
|
" - 'text': original text\n",
|
|
" - 'token_count': number of tokens\n",
|
|
" - 'char_count': number of characters\n",
|
|
" - 'avg_chars_per_token': average characters per token\n",
|
|
" - 'tokens': list of token IDs\n",
|
|
" - 'decoded_tokens': list of decoded token strings\n",
|
|
" - 'unique_tokens': number of unique tokens\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" tokens = encoding.encode(text)\n",
|
|
" decoded_tokens = [encoding.decode([t]) for t in tokens]\n",
|
|
" token_count = len(tokens)\n",
|
|
" char_count = len(text)\n",
|
|
" avg_chars_per_token = char_count / token_count if token_count > 0 else 0\n",
|
|
" unique_tokens = len(set(tokens))\n",
|
|
"\n",
|
|
" return {\n",
|
|
" \"text\": text,\n",
|
|
" \"token_count\": token_count,\n",
|
|
" \"char_count\": char_count,\n",
|
|
" \"avg_chars_per_token\": avg_chars_per_token,\n",
|
|
" \"tokens\": tokens,\n",
|
|
" \"decoded_tokens\": decoded_tokens,\n",
|
|
" \"unique_tokens\": unique_tokens,\n",
|
|
" }\n",
|
|
"\n",
|
|
"\n",
|
|
"# Test cases\n",
|
|
"test_texts = [\n",
|
|
" \"Hello, world!\",\n",
|
|
" \"The quick brown fox jumps over the lazy dog.\",\n",
|
|
" \"Machine learning and artificial intelligence are transforming technology.\",\n",
|
|
" \"café résumé naïve\", # Test with accents\n",
|
|
"]\n",
|
|
"\n",
|
|
"for text in test_texts:\n",
|
|
" result = analyze_tokenization(text)\n",
|
|
" print(f\"\\nText: {result['text']}\")\n",
|
|
" print(f\"Tokens: {result['token_count']}\")\n",
|
|
" print(f\"Chars per token: {result['avg_chars_per_token']:.2f}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"id": "681f8fef",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Text: Short prompt...\n",
|
|
"Input tokens: 2\n",
|
|
"Input cost: $0.000000\n",
|
|
"Est. output cost: $0.000002\n",
|
|
"Total: $0.000002\n",
|
|
"\n",
|
|
"Text: This is a medium-length prompt with more details a...\n",
|
|
"Input tokens: 12\n",
|
|
"Input cost: $0.000002\n",
|
|
"Est. output cost: $0.000011\n",
|
|
"Total: $0.000013\n",
|
|
"\n",
|
|
"Text: This is a very long prompt with extensive context,...\n",
|
|
"Input tokens: 35\n",
|
|
"Input cost: $0.000005\n",
|
|
"Est. output cost: $0.000031\n",
|
|
"Total: $0.000036\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def calculate_api_cost(\n",
|
|
" text: str,\n",
|
|
" input_cost_per_1m: float = 0.15,\n",
|
|
" output_cost_per_1m: float = 0.60,\n",
|
|
") -> dict:\n",
|
|
" \"\"\"Calculate API costs based on token count, Using GPT-4o pricing as example.\n",
|
|
"\n",
|
|
" Args:\n",
|
|
" text: Input text\n",
|
|
" input_cost_per_1m: Cost per 1M input tokens (default: $0.15)\n",
|
|
" output_cost_per_1m: Cost per 1M output tokens (default: $0.60)\n",
|
|
"\n",
|
|
" Returns:\n",
|
|
" Dictionary with input cost, estimated output cost, and total\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" # 1. Count tokens in input\n",
|
|
" input_tokens = count_tokens(text)\n",
|
|
" input_cost = (input_tokens / 1_000_000) * input_cost_per_1m\n",
|
|
"\n",
|
|
" # 2. Estimate output tokens (assume 1.5x input for generation)\n",
|
|
" estimated_output_tokens = int(input_tokens * 1.5)\n",
|
|
" output_cost = (estimated_output_tokens / 1_000_000) * output_cost_per_1m\n",
|
|
"\n",
|
|
" # 3. Calculate total cost\n",
|
|
" total_cost = input_cost + output_cost\n",
|
|
"\n",
|
|
" # 4. Return detailed breakdown\n",
|
|
" return {\n",
|
|
" \"input_tokens\": input_tokens,\n",
|
|
" \"input_cost\": input_cost,\n",
|
|
" \"estimated_output_tokens\": estimated_output_tokens,\n",
|
|
" \"output_cost\": output_cost,\n",
|
|
" \"total_cost\": total_cost,\n",
|
|
" }\n",
|
|
"\n",
|
|
"\n",
|
|
"# Test with different text lengths\n",
|
|
"test_cases = [\n",
|
|
" \"Short prompt\",\n",
|
|
" \"This is a medium-length prompt with more details and context.\",\n",
|
|
" \"\"\"This is a very long prompt with extensive context, detailed instructions,\n",
|
|
" and multiple examples that will consume significantly more tokens when sent\n",
|
|
" to the API for processing and generation.\"\"\",\n",
|
|
"]\n",
|
|
"\n",
|
|
"for text in test_cases:\n",
|
|
" cost_info = calculate_api_cost(text)\n",
|
|
" print(f\"\\nText: {text[:50]}...\")\n",
|
|
" print(f\"Input tokens: {cost_info['input_tokens']}\")\n",
|
|
" print(f\"Input cost: ${cost_info['input_cost']:.6f}\")\n",
|
|
" print(f\"Est. output cost: ${cost_info['output_cost']:.6f}\")\n",
|
|
" print(f\"Total: ${cost_info['total_cost']:.6f}\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"id": "42ae078f",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Original text: 117 tokens\n",
|
|
"Number of chunks: 2\n",
|
|
"\n",
|
|
"Chunk 1: 85 tokens\n",
|
|
"Text: \n",
|
|
"Artificial intelligence is revolutionizing multiple industries. Machine learning\n",
|
|
"algorithms can now...\n",
|
|
"\n",
|
|
"Chunk 2: 142 tokens\n",
|
|
"Text: carefully consider the ethical implications of AI deployment. Data privacy and algorithmic bias are ...\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def chunk_text_by_tokens(\n",
|
|
" text: str,\n",
|
|
" max_tokens: int = 512,\n",
|
|
" overlap_tokens: int = 50,\n",
|
|
") -> list[str]:\n",
|
|
" \"\"\"Split text into chunks with maximum token count and overlap.\n",
|
|
"\n",
|
|
" Args:\n",
|
|
" text: Long text to split\n",
|
|
" max_tokens: Maximum tokens per chunk\n",
|
|
" overlap_tokens: Number of overlapping tokens between chunks\n",
|
|
"\n",
|
|
" Returns:\n",
|
|
" List of text chunks\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" # 1. Split text into sentences\n",
|
|
" sentences = text.split(\". \") # Simple sentence splitter (can be improved)\n",
|
|
"\n",
|
|
" # 2. Group sentences into chunks under token limit\n",
|
|
" chunks = []\n",
|
|
" current_chunk = []\n",
|
|
" current_tokens = 0\n",
|
|
"\n",
|
|
" for sentence in sentences:\n",
|
|
" sentence_tokens = count_tokens(sentence)\n",
|
|
" if current_tokens + sentence_tokens > max_tokens:\n",
|
|
" # Add current chunk to list\n",
|
|
" chunks.append(\". \".join(current_chunk) + \".\")\n",
|
|
" # Start new chunk with overlap\n",
|
|
" current_chunk = [*current_chunk[-overlap_tokens:], sentence]\n",
|
|
" current_tokens = sum(count_tokens(s) for s in current_chunk)\n",
|
|
" else:\n",
|
|
" current_chunk.append(sentence)\n",
|
|
" current_tokens += sentence_tokens\n",
|
|
"\n",
|
|
" # Add any remaining chunk\n",
|
|
" if current_chunk:\n",
|
|
" chunks.append(\". \".join(current_chunk) + \".\")\n",
|
|
"\n",
|
|
" # 3. Add overlap between chunks\n",
|
|
" for i in range(1, len(chunks)):\n",
|
|
" overlap = \" \".join(chunks[i - 1].split()[-overlap_tokens:])\n",
|
|
" chunks[i] = overlap + \" \" + chunks[i]\n",
|
|
" # 4. Return list of chunks\n",
|
|
" return chunks\n",
|
|
"\n",
|
|
"\n",
|
|
"# Test with a long document\n",
|
|
"long_text = \"\"\"\n",
|
|
"Artificial intelligence is revolutionizing multiple industries. Machine learning\n",
|
|
"algorithms can now process vast amounts of data with unprecedented efficiency.\n",
|
|
"Deep learning models have achieved remarkable results in computer vision and\n",
|
|
"natural language processing tasks. The integration of AI into business processes\n",
|
|
"is creating new opportunities and challenges. Companies must carefully consider\n",
|
|
"the ethical implications of AI deployment. Data privacy and algorithmic bias\n",
|
|
"are critical concerns that require ongoing attention. The future of AI development\n",
|
|
"will likely focus on creating more interpretable and trustworthy systems.\n",
|
|
"Researchers are actively working on techniques to improve model transparency\n",
|
|
"and accountability.\n",
|
|
"\"\"\"\n",
|
|
"\n",
|
|
"chunks = chunk_text_by_tokens(long_text, max_tokens=100, overlap_tokens=20)\n",
|
|
"print(f\"Original text: {count_tokens(long_text)} tokens\")\n",
|
|
"print(f\"Number of chunks: {len(chunks)}\")\n",
|
|
"for i, chunk in enumerate(chunks, 1):\n",
|
|
" print(f\"\\nChunk {i}: {count_tokens(chunk)} tokens\")\n",
|
|
" print(f\"Text: {chunk[:100]}...\")\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "studies (3.13.9)",
|
|
"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.13.9"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|