โทเคนและค่าใช้จ่าย API โมเดลใหญ่: การประมาณค่า การอ่าน งบประมาณ และตัวอย่าง
การใช้ API โมเดลใหญ่คล้ายการใช้ไฟฟ้าหรือน้ำ: หากไม่ดูมิเตอร์ บิลสิ้นเดือนอาจทำให้ตกใจ; หากอ่านเป็น จะรู้จำนวนการใช้ทุกหน่วย มิเตอร์ในที่นี้คือตัวนับโทเคน บทความนี้เริ่มจากอธิบายว่าโทเคนคืออะไร วิธีประมาณการภาษาจีน/อังกฤษ จากนั้นสอนวิธีอ่านฟิลด์ usage ใน response ติดตั้งเกตงบประมาณในโปรแกรม และใช้ตัวอย่าง 3 กรณีที่ระบุสมมติฐาน เพื่อคำนวณราคาอินพุต $0.25 และเอาต์พุต $1.00 ต่อหนึ่งล้านโทเคนในสถานการณ์จริง
อัปเดตเมื่อ
จุดสำคัญ
- สูตรคำนวณ: (โทเคนอินพุต × $0.25 + โทเคนเอาต์พุต × $1.00) ÷ 1,000,000
- การประมาณใช้เพื่อทำนายล่วงหน้าเท่านั้น ปริมาณจริงดูจาก usage ใน response การตอบสนองแบบสตรีมมิงจะรวม usage ไว้ในบล็อกสุดท้าย
- ต้นทุนหลักของแอปพลิเคชันสนทนาคือประวัติที่ส่งซ้ำๆ การตัดประวัติเป็นวิธีที่คุ้มค่าที่สุด
- 3 วิธีควบคุมงบประมาณ: จำกัด max_tokens จำกัดความยาวประวัติ และสะสมค่าใช้จ่ายในโปรแกรมพร้อมตั้งขีดจำกัดรายวัน
โทเคนคืออะไร และคำนวณเงินอย่างไร
โทเคนคือหน่วยวัดขั้นต่ำที่โมเดลประมวลผลข้อความ ไม่ใช่ตัวอักษรหรือคำ แต่เป็น "เศษ" ระหว่างกลาง สามารถนึกภาพเป็นขีดบนมิเตอร์น้ำ: ยิ่งใช้มาก ขีดยิ่งเดินเร็ว การคิดค่าแบ่งเป็นสองส่วน:
| รายการ | ราคาต่อหน่วย (ต่อล้านโทเคน) | รวมอะไรบ้าง |
|---|---|---|
| อินพุต | $0.25 | เนื้อหาทั้งหมดใน messages: system, ประวัติ, คำถามปัจจุบัน |
| เอาต์พุต | $1.00 | ข้อความตอบกลับที่โมเดลสร้าง |
หมายเหตุ: ราคาเอาต์พุตสูงกว่าอินพุต 4 เท่า ดังนั้นการทำให้โมเดล "พูดน้อยลง" มักประหยัดกว่าการ "ส่งบริบทน้อยลง" แต่ในสถานการณ์สนทนา อินพุตจะขยายตัวเนื่องจากประวัติสะสม จึงต้องจัดการทั้งสองด้าน การชำระเงินใช้ยอดเงินเติมเงินล่วงหน้า ไม่ใช่แบบสมัครสมาชิก ยอดเงินไม่หมดอายุ บัญชีใหม่มีเครดิตทดลองใช้ $0.50 ใช้ได้ภายใน 7 วัน
จุดที่มักสับสน: จำนวนโทเคนที่ส่งออกคือจำนวนที่โมเดลสร้างจริง ไม่ใช่ค่า max_tokens ที่คุณตั้งค่า max_tokens เป็นเพียงขีดจำกัด หากโมเดลตอบจบที่ 200 ตัวอักษร คุณจะเสียเงินตามโทเคนของ 200 ตัวอักษรนั้น แต่ในการวางแผนงบประมาณ ควรคำนวณจากขีดจำกัดเพื่อเตรียมรับมือกับผลลัพธ์ที่ยาวเกินคาด
การประมาณล่วงหน้า: การประมาณค่าภาษาจีนและอังกฤษ
ก่อนส่งคำขอ ทำได้แค่ประมาณ ค่าด้านล่างเป็นค่าประมาณ อาจมีความคลาดเคลื่อนตามเนื้อหา:
| ข้อความ | กฎการประมาณค่า | ตัวอย่าง (สมมติ) |
|---|---|---|
| ภาษาจีน | ประมาณ 1 ถึง 1.5 โทเคนต่อตัวอักษร | 3,000 ตัวอักษร ประมาณ 3,000 ถึง 4,500 โทเคน |
| ภาษาอังกฤษ | ประมาณ 1 โทเคนต่อ 4 ตัวอักษร หรือประมาณ 1.3 โทเคนต่อคำ | 1,000 คำ ประมาณ 1,300 โทเคน |
| ข้อความผสมจีน-อังกฤษ โค้ด | ประมาณค่าด้วยค่าที่สูงกว่า | เนื้อหาที่มี JSON และสัญลักษณ์ใช้ทรัพยากรมากกว่า |
การใช้การประมาณที่ถูกต้องคือการ "判斷ขนาด": บทความนี้มีขนาดประมาณหนึ่งหมื่นหรือแสนโทเคน จะเกินหน้าต่างบริบท 100,000 หรือไม่ การเรียกครั้งเดียวคิดเงินกี่เซ็นต์ เพื่อความแม่นยำ ให้อ่าน usage โดย好习惯คือสุ่มรันแต่ละสถานการณ์ธุรกิจหลายสิบครั้ง แล้วหาค่าเฉลี่ยของ usage เพื่อใช้แทนค่าประสบการณ์
ยกตัวอย่างการผสมผสานระหว่างการประมาณและค่าจริง สมมติว่าคุณต้องประมวลผลคำติชมลูกค้าภาษาจีนขนาดประมาณ 2,000 ตัวอักษร โดยประมาณที่ 1.3 โทเคนต่อตัวอักษร ต่อรายการประมาณ 2,600 โทเคน บวกคำสั่ง 200 โทเคน อินพุตรวมประมาณ 2,800 โทเคน เลือก 30 รายการมาทดสอบ อ่านค่าเฉลี่ยจาก usage สมมติว่าค่าเฉลี่ยจริงคือ 2,500 ให้ปรับสัมประสิทธิ์ของคุณเป็นประมาณ 1.15 จากนั้นคำนวณงบประมาณสำหรับทั้งชุดโดยใช้สัมประสิทธิ์ที่ปรับแล้ว ความคลาดเคลื่อนจะน้อยลงมาก ตัวเลขทดสอบนี้เป็นเพียงสมมติฐานเพื่อสาธิตวิธีการ ข้อมูลของคุณจะมีค่าของตัวเอง
อ่าน usage: การอ่านมิเตอร์ที่แท้จริง
ทุก response ที่สำเร็จจะมี usage ซึ่งประกอบด้วย prompt_tokens, completion_tokens และ total_tokens การสตรีมไม่ต้องการพารามิเตอร์เพิ่ม แต่จะเพิ่มบล็อกข้อมูลที่มี usage เป็นบล็อกสุดท้าย โค้ดด้านล่างสาธิตการอ่านทั้งสองแบบและแปลงค่าเป็นดอลลาร์:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.apidamoxing.com/v1", api_key=os.environ["API_KEY"])
PRICE_IN, PRICE_OUT = 0.25, 1.00 # 美元 / 百万 token
def cost(u):
return (u.prompt_tokens * PRICE_IN + u.completion_tokens * PRICE_OUT) / 1_000_000
# 非流式:usage 在响应对象上
r = client.chat.completions.create(
model="uncensored", max_tokens=200,
messages=[{"role": "user", "content": "用三句话解释什么是通货膨胀。"}],
)
print(r.usage.prompt_tokens, r.usage.completion_tokens, f"${cost(r.usage):.6f}")
# 流式:最后一个数据块带 usage,其余块的 usage 为空
usage_last = None
stream = client.chat.completions.create(
model="uncensored", max_tokens=200, stream=True,
messages=[{"role": "user", "content": "再用三句话解释什么是通货紧缩。"}],
)
for chunk in stream:
if chunk.usage:
usage_last = chunk.usage
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
if usage_last:
print(usage_last.prompt_tokens, usage_last.completion_tokens, f"${cost(usage_last):.6f}")เมื่อสตรีมมิงต้องระวัง: มีเฉพาะบล็อกสุดท้ายเท่านั้นที่มี usage บล็อกก่อนหน้าจะเป็นค่าว่าง ดังนั้นใช้ if chunk.usage เพื่อตรวจสอบ บันทึกการอ่านแต่ละครั้งลงในบันทึกหรือฐานข้อมูล เพื่อตรวจสอบยอดสิ้นเดือน หาความผิดปกติ และคำนวณต้นทุนต่อผู้ใช้
นิสัยอีกอย่างที่น่าทำคือการทำแท็กให้แต่ละฟีเจอร์ธุรกิจ เพื่อจดบันทึกพร้อมกัน เช่น แยกบันทึก "สรุป", "บริการลูกค้า", "แปลภาษา" เมื่อสิ้นเดือนจะเห็นทันทีว่าฟีเจอร์ไหนใช้เงินมากที่สุด ควรปรับพรอมต์ ตัดประวัติ หรือลด max_tokens หรือไม่ หากไม่มีแท็ก มีเพียงยอดรวม การจะปรับปรุงก็ทำได้ยาก
ตัวอย่างการคำนวณ 3 กรณี (เงื่อนไขสมมติระบุไว้แล้ว)
กรณีศึกษาที่ 1: การตอบคำถามบริการลูกค้า
สมมติ: คำขอแต่ละครั้งมีอินพุต 800 โทเคน (รวม system และส่วนความรู้) เอาต์พุต 200 โทเคน; 10,000 ครั้งต่อวัน
ค่าใช้จ่ายต่อครั้ง: อินพุต 800 × 0.25 ÷ 1,000,000 = $0.0002, เอาต์พุต 200 × 1.00 ÷ 1,000,000 = $0.0002, รวม $0.0004 ต่อครั้ง ต่อวัน $4.00, 30 วัน $120 ด้วยอัตรานี้ เครดิตทดลองใช้ $0.50 จะรองรับการเรียกใช้ประมาณ 1,250 ครั้ง
กรณีศึกษาที่ 2: การสรุปย่อบทความยาว
สมมติ: บทความละอินพุต 20,000 โทเคน เอาต์พุตสรุปย่อ 600 โทเคน; รวม 500 บทความ
ต่อบทความ: อินพุต 20,000 × 0.25 ÷ 1,000,000 = $0.005, เอาต์พุต 600 × 1.00 ÷ 1,000,000 = $0.0006, รวม $0.0056 ต่อบทความ 500 บทความรวม $2.80 จะเห็นว่างานที่มีอินพุตยาวแต่เอาต์พุตสั้นมีต้นทุนต่ำมาก
กรณีศึกษาที่ 3: แชทหลายรอบและการตัดประวัติ
สมมติ: system 100 โทเคน; แต่ละรอบอินพุตผู้ใช้ 60 โทเคน เอาต์พุต 150 โทเคน; การสนทนา 1 รอบมี 20 รอบ
| แนวทาง | โทเคนอินพุตสะสม | โทเคนเอาต์พุตสะสม | ค่าใช้จ่ายรวม |
|---|---|---|---|
| ส่งประวัติทั้งหมดทุกครั้ง | 43,100 | 3,000 | ประมาณ $0.0138 |
| ส่งเฉพาะ 3 รอบล่าสุด | 14,540 | 3,000 | ประมาณ $0.0066 |
แนวทางส่งประวัติทั้งหมดมีอินพุต: 20 × (100 + 60) + 210 × (0 + 1 + … + 19) = 3,200 + 39,900 = 43,100 โทเคน แนวทางตัดประวัติ 3 รอบแรกมี 160, 370, 580 โทเคน ตามลำดับ รอบที่ 4 ถึง 20 มีรอบละ 790 โทเคน รวม 14,540 โทเคน ค่าใช้จ่ายต่างกันประมาณครึ่งหนึ่ง ยิ่งสนทนาหลายรอบความแตกต่างยิ่งมาก เพราะอินพุตของแนวทางส่งประวัติทั้งหมดเพิ่มขึ้นแบบกำลังสองตามจำนวนรอบ
จากตัวอย่างทั้งสามสามารถสรุปเป็นสูตรประสบการณ์ได้ว่า ต้นทุนถูกกำหนดโดย “จำนวนคำขอ × ปริมาณอินพุต/เอาต์พุตต่อครั้ง” โดยปริมาณอินพุตต่อครั้งนั้น ประวัติและเอกสารประกอบคือส่วนที่สามารถปรับลดได้มากที่สุด การลดขนาดส่วนความรู้ในกรณีบริการลูกค้า การตัดประวัติในกรณีแชท และการแบ่งบล็อกทำแบบขนานในกรณีสรุปย่อ ล้วนเป็นหลักการเดียวกัน: อย่าจ่ายโทเคนส่วนเกินโดยไม่จำเป็น ขอเน้นว่าตัวเลขในตัวอย่างทั้งสามมาจากสมมติที่ระบุไว้ข้างต้น ข้อมูลการใช้งานจริงของคุณควรอ้างอิงจาก usage
ลองคำนวณย้อนกลับอีกกรณี: หากงบประมาณรายเดือนของคุณคือ $30 และต้องการทราบว่าผลิตภัณฑ์แชทจะรองรับการสนทนา 20 รอบได้กี่ครั้งต่อเดือน ด้วยแนวทาง “ส่งเฉพาะ 3 รอบล่าสุด” จากกรณีศึกษาที่ 3 แต่ละครั้งประมาณ $0.0066 $30 ÷ 0.0066 จะรองรับได้ประมาณ 4,545 ครั้ง หากใช้แนวทางส่งประวัติทั้งหมดด้วยงบประมาณเดียวกัน แต่ละครั้ง $0.0138 จะรองรับได้ประมาณ 2,174 ครั้ง นี่คือความแตกต่างที่แท้จริงจากการตัดประวัติ
การควบคุมงบประมาณ: ติดตั้งเกตในโปรแกรม
การประมาณการเป็นเพียงการทำนาย ประตูน้ำคือหลักประกัน ด้านล่างคือคลาสงบประมาณรายวันที่บันทึกเป็นดอลลาร์: ก่อนคำขอใช้การคาดการณ์ “กรณีเลวร้าย” (เอาต์พุตใช้เต็ม max_tokens) หลังคำขอใช้ usage จริงในการบันทึก
class Budget:
"""按美元计的日预算。超出时拒绝新请求。"""
def __init__(self, daily_usd):
self.limit = daily_usd
self.spent = 0.0
def check(self, est_prompt_tokens, max_tokens):
# 最坏情况:输出用满 max_tokens
worst = (est_prompt_tokens * 0.25 + max_tokens * 1.00) / 1_000_000
if self.spent + worst > self.limit:
raise RuntimeError(f"预算不足:已用 ${self.spent:.4f},本次最坏 ${worst:.4f},上限 ${self.limit}")
def record(self, usage):
self.spent += (usage.prompt_tokens * 0.25 + usage.completion_tokens * 1.00) / 1_000_000
budget = Budget(daily_usd=5.0)
budget.check(est_prompt_tokens=1200, max_tokens=500) # 请求前
# ……发请求……
# budget.record(response.usage) # 请求后นอกจากเกตในโปรแกรม ยังมีวิธีการในระดับการตั้งค่า 3 แบบ:
- ตั้งค่า max_tokens ตามงาน อย่าดึงขึ้นสูงสุดเสมอไป ค่าเริ่มต้นคือ 2,048 สูงสุด 32,000;
- กำหนดความยาวสูงสุดสำหรับประวัติการสนทนา ดูวิธีการในการสร้างแชทบอท;
- เติมเงินในบัญชีเฉพาะจำนวนที่คุณวางแผนจะใช้ เติมเมื่อหมด รูปแบบการชำระเงินล่วงหน้าเป็นขีดจำกัดแข็งโดยธรรมชาติ
ราคาและกฎยอดคงเหลืออ้างอิงหน้าราคา รายละเอียดอินเทอร์เฟซอยู่ในคำอธิบายพารามิเตอร์
สรุปเป็นรายการตรวจสอบ: ก่อนทำ การประมาณการขนาด การตั้งค่า max_tokens และการตรวจสอบความยาวประวัติ; ระหว่างทำ ระวัง usage ของบล็อกสุดท้ายเมื่อเอาต์พุตแบบสตรีมมิง; หลังทำ บันทึกและจัดหมวดหมู่ตามฟังก์ชัน เปรียบเทียบกับงบประมาณ ทำครบ 3 ขั้นตอนบัญชีจะชัดเจน
คำถามที่พบบ่อย
โทเคนอินพุตและเอาต์พุตต้องจ่ายทั้งคู่หรือไม่?
ใช่ อินพุตหนึ่งล้านโทเคน $0.25 และเอาต์พุตหนึ่งล้านโทเคน $1.00 คำนวณแยกกันตาม prompt_tokens และ completion_tokens ในฟิลด์ usage
ฉันสามารถคำนวณค่าใช้จ่ายที่แน่นอนล่วงหน้าได้หรือไม่?
ทำได้เพียงประมาณการขนาดเท่านั้น ตัวเลขที่แม่นยำต้องดูจาก usage ในการตอบกลับ แนะนำให้สุ่มเก็บค่าเฉลี่ยในแต่ละสถานการณ์เพื่อใช้ทำนาย
ยอดคงเหลือหมดอายุหรือไม่?
ยอดคงเหลือแบบเติมเงินจะไม่หมดอายุ เครดิตทดลองใช้ $0.50 สำหรับบัญชีใหม่มีอายุ 7 วัน
จะหลีกเลี่ยงไม่ให้การสนทนาแพงขึ้นเรื่อยๆ ได้อย่างไร?
จำกัดความยาวของประวัติที่ส่งเข้าไป โดยเก็บเพียงไม่กี่รอบล่าสุด หรือบีบอัดเนื้อหาเก่าให้เป็นบทสรุป พร้อมตั้งค่า max_tokens ให้เหมาะสมกับงาน
กรอกแบบฟอร์มเพื่อรับคีย์
สร้างบัญชี คัดลอกคีย์ และแก้ไข Base URL การกำหนดค่าก็ง่ายแค่นี้