uttapen

توکن چیست و یک درخواست فارسی چند توکن است؟ (با اعداد واقعی)

توکن در مدل‌های زبانی چیست، چرا فارسی تقریباً دو برابر انگلیسی توکن مصرف می‌کند، و شمارش واقعی پنج نمونهٔ فارسی با tiktoken همراه با هزینهٔ تومانی.

۱۶ شهریور ۱۴۰۵ · ۹ دقیقه مطالعه · تیم یوتاپن

هر صورت‌حساب مدل زبانی بر حسب توکن است، ولی کمتر کسی می‌داند یک جملهٔ فارسی معمولی چند توکن است و چرا این عدد از جملهٔ انگلیسی هم‌معنایش بیشتر درمی‌آید. در این مقاله به‌جای تعریف کلی، پنج متن فارسی واقعی را با همان توکنایزری که مدل‌های OpenAI استفاده می‌کنند شمرده‌ایم و اعداد را کنار هزینهٔ تومانی گذاشته‌ایم. کد شمارش هم هست تا با متن‌های خودت تکرارش کنی.

توکن دقیقاً چیست

مدل زبانی با حروف کار نمی‌کند و با کلمه هم کار نمی‌کند؛ با واحدی بین این دو کار می‌کند که به آن توکن می‌گویند. توکنایزر یک جدول بزرگ از تکه‌رشته‌های پرتکرار دارد (برای مدل‌های جدید OpenAI این جدول به نام o200k_base حدود دویست هزار تکه دارد) و هر متن ورودی را به دنباله‌ای از این تکه‌ها می‌شکند. تکه‌ها با الگوریتمی به نام Byte Pair Encoding از روی حجم عظیمی از متن ساخته شده‌اند: هر چه یک دنباله از بایت‌ها در آن متن‌ها پرتکرارتر بوده، احتمال اینکه یک توکن مستقل شده باشد بیشتر است. برای همین کلمهٔ انگلیسی the یک توکن است، ولی یک کلمهٔ کم‌تکرار ممکن است سه چهار توکن شود.

ببین جملهٔ «سلام! خودت را معرفی کن.» چطور شکسته می‌شود:

'سلام' | '!' | ' خود' | 'ت' | ' را' | ' معرفی' | ' کن' | '.'

هشت توکن برای پنج کلمه. دقت کن که فاصله جزو توکن بعدی است ( را نه را)، و «خودت» به دو تکهٔ «خود» و «ت» شکسته شده چون پسوند ملکی برای توکنایزر یک واحد جدا است. این شکستن هیچ ربطی به معنا ندارد؛ فقط آمار است.

چرا فارسی بیشتر توکن می‌خورد

جدول توکن‌ها از متنی ساخته شده که سهم انگلیسی در آن بسیار بیشتر از فارسی است. در نتیجه تکه‌های انگلیسی بلندتر و فارسی کوتاه‌ترند. به علاوه، هر حرف فارسی در UTF-8 دو بایت است، پس حتی در سطح بایت هم متن فارسی از انگلیسی هم‌طولش سنگین‌تر است. نتیجهٔ عملی: برای یک معنای مشخص، فارسی حدود ۱٫۵ تا ۲ برابر انگلیسی توکن می‌گیرد، و چون قیمت به‌ازای توکن است، یعنی همان نسبت گران‌تر.

توکنایزر قدیمی‌تر OpenAI به نام cl100k_base (مدل‌های نسل GPT-4 اولیه) برای فارسی به‌مراتب بدتر بود؛ در جدول پایین ستونش هست تا ببینی نسل جدید چقدر بهتر شده. مدل‌های Claude، Gemini و DeepSeek هر کدام توکنایزر خودشان را دارند و عدد دقیق‌شان فرق می‌کند، ولی الگوی کلی (فارسی گران‌تر از انگلیسی) در همه‌شان برقرار است. عدد قطعی برای هر مدل، همان usage.prompt_tokens است که در پاسخ برمی‌گردد.

پنج نمونهٔ واقعی

این پنج متن را با tiktoken نسخهٔ ۰٫۱۴ و جدول o200k_base شمردیم. ستون «کلمه» شمارش سادهٔ با فاصله است.

نمونهنویسهکلمهتوکن (o200k)توکن (cl100k)توکن به‌ازای کلمه
سلام کوتاه: «سلام! خودت را معرفی کن.»۲۳۵۸۱۷۱٫۶۰
درخواست ایمیل: «لطفاً یک ایمیل رسمی برای مدیرم بنویس که…»۸۷۱۷۳۱۶۹۱٫۸۲
پاراگراف فنی دربارهٔ تغییر base_url۲۱۴۳۶۶۰۱۱۷۱٫۶۷
بیت شعر به‌اضافهٔ درخواست توضیح برای دانش‌آموز۱۶۸۳۶۶۱۱۲۶۱٫۶۹
پیام system یک دستیار فروشگاه۳۲۳۵۸۱۱۱۲۴۰۱٫۹۱
جمع پنج نمونه۸۱۵۱۵۲۲۷۱۵۶۹۱٫۷۸

برای مقایسه، معادل انگلیسی همان درخواست ایمیل (۲۰ کلمه) فقط ۲۱ توکن شد، یعنی ۱٫۰۵ توکن به‌ازای هر کلمه. و «Hi! Introduce yourself.» شش توکن گرفت در برابر هشت توکن نسخهٔ فارسی.

عدد کلیدی که باید به خاطر بسپاری: هر کلمهٔ فارسی تقریباً ۱٫۸ توکن است. با این ضریب می‌توانی بدون اجرای هیچ کدی هزینهٔ تقریبی هر پرامپت را حساب کنی: هزار کلمهٔ فارسی، حدود ۱٬۸۰۰ توکن. متن‌های رسمی و اداری با کلمات بلند و ترکیب‌های پسونددار (مثل همان پیام system فروشگاه) به ۱٫۹ می‌رسند و متن فنی پر از اصطلاح لاتین پایین‌تر می‌آید، چون کلمات انگلیسی ارزان‌ترند.

چند یافتهٔ غیرمنتظره

هنگام شمردن، چند چیز را هم امتحان کردیم که جواب‌شان با تصور اولیه فرق داشت:

  • نیم‌فاصله توکن اضافه نمی‌گیرد. «می‌آیم» با نیم‌فاصله، با فاصلهٔ کامل، و چسبیده، هر سه دقیقاً سه توکن شدند. پس لازم نیست برای صرفه‌جویی، نیم‌فاصله‌ها را از متن کاربر بگیری.
  • ارقام فارسی دو برابر ارقام لاتین هزینه دارند. «۱۲۳۴۵» چهار توکن است ولی «12345» دو توکن. «۱٬۲۰۰٬۰۰۰ تومان» هشت توکن و «1,200,000 تومان» شش توکن. اگر داده‌های عددی زیادی (فاکتور، جدول قیمت، گزارش) به مدل می‌دهی، تبدیل ارقام به لاتین قبل از ارسال، صرفه‌جویی واقعی است و در دقت مدل هم اثری ندارد.
  • رشته‌های تصادفی خیلی گران‌اند. یک کلید API چهل‌کاراکتری ۳۱ توکن می‌گیرد. شناسه‌های UUID، هش‌ها و توکن‌های تصادفی را از پرامپت بیرون نگه دار؛ نه به خاطر پول، بلکه چون مدل هم از آن‌ها چیزی نمی‌فهمد.
  • شکلک یک توکن است. اما جواب مدل با شکلک لزوماً ارزان نیست، چون بعضی شکلک‌های ترکیبی چند توکن‌اند.

این توکن‌ها چند تومان می‌شود

قیمت هر مدل به‌ازای یک میلیون توکن اعلام می‌شود، پس هزینهٔ توکن‌های ورودی همان پنج نمونه این‌طور درمی‌آید (فقط ورودی؛ پاسخ مدل جدا حساب می‌شود و معمولاً گران‌تر است):

نمونهتوکنبا GPT-5 miniبا DeepSeek V3با Claude Sonnet 4.5
سلام کوتاه۸۰٫۲۶ تومان۰٫۳۴ تومان۳٫۱۶ تومان
درخواست ایمیل۳۱۱٫۰۲ تومان۱٫۳۱ تومان۱۲٫۲۶ تومان
پاراگراف فنی۶۰۱٫۹۸ تومان۲٫۵۳ تومان۲۳٫۷۴ تومان
بیت شعر و توضیح۶۱۲٫۰۱ تومان۲٫۵۷ تومان۲۴٫۱۳ تومان
پیام system فروشگاه۱۱۱۳٫۶۶ تومان۴٫۶۸ تومان۴۳٫۹۱ تومان

این اعداد کوچک‌اند و همین کوچکی گمراه‌کننده است. پیام system فروشگاه در هر درخواست تکرار می‌شود؛ با ده هزار گفتگوی ماهانه و میانگین شش رفت‌وبرگشت در هر گفتگو، فقط همان ۱۱۱ توکن روی Claude Sonnet می‌شود بیش از دو میلیون و ششصد هزار تومان در ماه، قبل از اینکه حتی یک کلمه پاسخ تولید شده باشد. جدول کامل قیمت مدل‌ها در مقالهٔ قیمت‌ها به تومان است.

خودت بشمار

پکیج tiktoken را نصب کن و همین کد را اجرا کن؛ خروجی جدول بالا از همین اسکریپت آمده:

# pip install tiktoken
import tiktoken

enc = tiktoken.get_encoding("o200k_base")   # توکنایزر GPT-4o و GPT-5

samples = {
    "سلام کوتاه": "سلام! خودت را معرفی کن.",
    "ایمیل": "لطفاً یک ایمیل رسمی برای مدیرم بنویس که بگویم فردا به دلیل مراجعه به پزشک دیرتر می‌آیم.",
}
for name, text in samples.items():
    ids = enc.encode(text)
    print(f"{name}: {len(text.split())} کلمه → {len(ids)} توکن")
    print("  ", [enc.decode([i]) for i in ids])

در Node معادلش پکیج js-tiktoken یا gpt-tokenizer است و در PHP پکیج yethee/tiktoken. برای مدل‌های غیر OpenAI، ساده‌ترین راه این است که یک درخواست کوچک بزنی و usage.prompt_tokens را بخوانی؛ همان عدد مبنای صورت‌حساب است.

توکن‌هایی که نمی‌بینی

وقتی messages می‌فرستی، فقط متن پیام‌ها شمرده نمی‌شود. هر پیام چند توکن سربار ساختاری دارد (نقش، جداکننده‌ها) که بسته به مدل بین سه تا هفت توکن به‌ازای هر پیام است. تعریف ابزارها در tools هم به‌صورت متن به مدل داده می‌شود و در هر درخواست شمرده می‌شود؛ یک اسکیمای متوسط با پنج تابع می‌تواند سیصد چهارصد توکن باشد. تصویر بسته به اندازه به چند صد تا چند هزار توکن تبدیل می‌شود. و در مدل‌های استدلالی، توکن‌های «فکر کردن» که در پاسخ نمی‌بینی، با قیمت خروجی شارژ می‌شوند و در usage.completion_tokens_details.reasoning_tokens گزارش می‌شوند.

دروازه چطور می‌شمارد

قبل از اینکه درخواست تو به مدل برسد، دروازهٔ uttapen متن پیام‌ها را با همین o200k_base می‌شمارد تا برآورد اولیهٔ هزینه را بسازد و همان مقدار را موقتاً از کیف پولت بلوکه کند. این فقط برآورد است؛ صورت‌حساب نهایی از روی usage واقعی که مدل گزارش می‌دهد بسته می‌شود، و برای مدل‌هایی که توکنایزر متفاوت دارند، اختلاف برآورد و واقعیت معمولاً زیر بیست درصد است و در هر حال به نفع یا ضرر تو نمی‌شود، چون مبلغ اضافهٔ بلوکه‌شده آزاد می‌گردد. عدد نهایی در هدر X-Uttapen-Cost-Toman هر پاسخ می‌آید.

چند کلمهٔ فارسی در پنجرهٔ context جا می‌شود

هر مدل یک سقف برای مجموع توکن‌های ورودی و خروجی یک درخواست دارد که به آن context window می‌گویند. با ضریب ۱٫۸، این سقف‌ها به زبان کلمهٔ فارسی این‌طور ترجمه می‌شوند: مدلی با ۲۰۰ هزار توکن (مثل Claude Haiku 4.5) حدود ۱۱۰ هزار کلمهٔ فارسی، مدلی با ۴۰۰ هزار توکن (مثل GPT-5) حدود ۲۲۰ هزار کلمه، و مدل‌های یک‌میلیون‌توکنی (Gemini 2.5 و GPT-4.1) بیش از نیم میلیون کلمه. یک کتاب سیصد صفحه‌ای فارسی حدود ۹۰ هزار کلمه یعنی نزدیک ۱۶۰ هزار توکن است؛ پس در مدل ۲۰۰ هزار توکنی جا می‌شود ولی جای زیادی برای پاسخ نمی‌ماند، و در مدل ۶۴ هزار توکنی مثل DeepSeek R1 اصلاً جا نمی‌شود و باید تکه‌تکه‌اش کنی.

دو هشدار: اول اینکه پر کردن context تا سقف، هم گران است (هر توکن ورودی پول دارد) و هم کیفیت پاسخ بیشتر مدل‌ها در انتهای پنجرهٔ خیلی بلند افت می‌کند. دوم اینکه سقف max_tokens خروجی هر مدل جدا از context است و معمولاً خیلی کمتر؛ در فیلد top_provider.max_completion_tokens پاسخ /v1/models می‌بینی‌اش.

سؤال‌های کوتاه

آیا می‌توانم قبل از ارسال، تعداد توکن دقیق را از API بگیرم؟ نه به‌صورت endpoint جدا؛ ولی همان tiktoken برای مدل‌های OpenAI دقیق است و برای بقیه، تخمین ۱٫۸ توکن به‌ازای هر کلمه برای بودجه‌بندی کافی است.

کلمهٔ انگلیسی داخل متن فارسی چطور شمرده می‌شود؟ ارزان‌تر از کلمهٔ فارسی؛ به همین دلیل پاراگراف فنی جدول بالا با وجود کلمات بلند، نسبت ۱٫۶۷ داشت. اصطلاحات فنی را ترجمه نکن؛ هم دقیق‌تر است، هم ارزان‌تر.

آیا حذف علائم نگارشی کمک می‌کند؟ خیلی کم. نقطه و ویرگول معمولاً هر کدام یک توکن‌اند، ولی حذف‌شان معنای متن را برای مدل مبهم می‌کند و جواب بدتر گران‌تر از چند توکن است.

سه توصیهٔ عملی

اول، طول پیام system را با همین ابزار بشمار و اگر بالای دویست توکن است، بپرس هر جمله‌اش واقعاً لازم است یا نه؛ این پیام در هر درخواست تکرار می‌شود. دوم، تاریخچهٔ گفتگو را محدود کن، چون هر پیام قدیمی که دوباره می‌فرستی، دوباره شمرده می‌شود. سوم، max_tokens را متناسب با کار بگذار؛ هم برآورد اولیه دقیق‌تر می‌شود و هم مدل تمایل کمتری به پرگویی دارد. اگر می‌خواهی این اعداد را روی متن‌های واقعی محصول خودت ببینی، یک کلید بساز و همان درخواست‌ها را با هدر X-Uttapen-Include-Meta بفرست؛ تعداد توکن و هزینهٔ هر کدام را در همان پاسخ می‌بینی.

مقاله‌های مرتبط

می‌خواهی همین کد را اجرا کنی؟

با شماره موبایل ثبت‌نام کن، کیف پول را شارژ کن و کلید بگیر. ساخت کلید API ←