Token:AI 时代的数字货币——从原理到计费全解

一、前言

Go 系列博文的最近一口气写了十篇(王婆卖瓜下,全是干货)。这一次换个方向,紧跟技术趋势,聊一个几乎所有 AI 应用都绕不开、却经常被一笔带过的概念------Token

在使用 ChatGPT、DeepSeek 等大模型时,你是否思考过:

  • 模型究竟是如何"阅读"我们输入的自然语言的?
  • 为什么在 API 计费中,看似长度相近的中文与英文,请求消耗的 Token 数却存在明显差异?

这些问题的答案,都指向同一个核心概念:Token

如果说算力是 AI 时代的"石油",那么 Token 更像是 AI 时代的"数字货币"。它既是大模型理解文本的最小语义单元,也是模型推理、上下文限制与 API 计费背后的统一度量标准。对开发者而言,Token 不只是一个抽象名词,而是一个需要被精确理解和管理的工程变量。

本文将从底层原理出发,系统拆解 Token 的生成与作用机制,并结合 Go 语言 ,手写一个简化版的 BPE(Byte Pair Encoding,字节对编码) 算法,带你从"知道 Token 是什么",走到"真正理解 Token 为什么是这样"。

二、什么是 Token?并非简单的"单词"

很多人直觉地认为:Token = 单词(Word)。但在 LLM(Large Language Model,大语言模型)的世界里,这个理解并不成立,甚至可以说是一个常见误区。

在模型内部,Token 并不是语言学意义上的"词",而是模型词表(Vocabulary )中的一个离散符号 ,在实现层面被映射为一个整数 ID 。它是一个介于自然语言与底层数学向量之间的桥梁,更偏向工程实现概念。

1. 不同语言下的 Token 表现形式

英文场景:以"子词"为核心

对于英文文本,Token 通常是子词(Subword)而非完整单词。

例如:

  • smart 往往是一个独立的 Token
  • smarter 可能被拆分为:
    • smart
    • er

这种拆分方式使模型能够复用高频词根,从而降低词表规模。

补充说明:关于"空格"

在切分时,英文单词前的空格 通常会被合并到 Token 中。例如 "apple"" apple" 会被识别为两个不同的编号。这解释了为什么 Prompt 结尾多一个空格有时会影响结果。

中文场景:并非"一字一 Token"

一个常见误解是:中文 = 一个汉字一个 Token。事实并非如此。

在实际模型中:

  • 某些高频汉字或词语(如"我们""中国")可能是单 Token
  • 低频字、罕见字、特殊符号,可能被拆成:
    • 多个 Token
    • 甚至多个字节级 Token

这完全取决于:

  • 模型的 Tokenizer 设计
  • 词表规模
  • 训练语料的分布

进阶视角:字节降级机制

当汉字不在词表时,它会按 UTF-8 编码拆成多个字节 Token。因此,中文在某些模型里比英文更"贵",因为一个汉字可能占用 2-3 个 Token 额度。

2. 为什么一定要做 Token 切分?

Tokenization 并不是为了"把文本拆开",而是一个在效率、语义与工程约束之间的权衡结果

2.1 字符级(Character-level):过于细碎

如果以单个字符作为最小单位(如 a, b, c你, 我, 他),序列长度极长,计算复杂度急剧上升,且语义被严重割裂("苹"和"果"分开看,很难直接关联到"苹果")。对于 Transformer 这种注意力模型而言,这是不可接受的。

2.2 单词级(Word-level):词表爆炸

如果以完整单词作为单位,英语存在时态、复数、派生词等变化,且新词层出不穷。这会导致词表规模无限膨胀,OOV(词表外词)问题严重,内存与参数规模失控,在工程上几乎不可行。

2.3 子词级(Subword-level):工程上的最优解

于是,大模型选择了折中方案:子词级 Token

核心思想是:高频词整体保留,低频词拆成更小的可复用单元

而这类方法中,最具代表性的算法之一,就是我们将在下一章详细拆解的:BPE(Byte Pair Encoding,字节对编码)

3. 一个关键认知:Token 是"模型世界"的最小单位

在模型内部:

  1. 文本 →\rightarrow→ Token 序列
  2. Token →\rightarrow→ 整数 ID
  3. 整数 ID →\rightarrow→ 向量(Embedding)

模型从头到尾都"看不到文字本身",它只认识 Token ID。这意味着:

  • 上下文长度限制,本质是 Token 数量限制
  • API 计费,本质是 Token 数量计费
  • Prompt 优化,本质是在 Token 级别做工程优化

理解 Token,不是为了"知道一个名词",而是为了真正理解大模型的运行成本与行为边界

4. 核心解密:模型是如何"读懂"这些数字的?

这可能是初学者最大的困惑:"把'苹果'变成了数字 5401,把'好吃'变成了 3922,模型只看到一堆数字,怎么就能理解语义并进行推理呢?"

在大模型的眼里,Token ID 只是一个索引。真正让它"活"过来的,是接下来发生的"查表 "与"特征动态聚合"。这个过程可以简化为三步:

A. 第一步:查字典 (Embedding) ------ 赋予身份

当模型接收到 Token ID 5401 时,它不会把这个数字拿去参与数学加减。相反,它会去查一张巨大的"权值表"------Embedding Matrix(嵌入矩阵)

在这张表里,5401 对应着一个由数千个浮点数组成的高维向量 ,比如 [0.12, -0.59, 0.88, ...]

  • 语义坐标 :你可以把这个向量看作 Token 在一个"万维空间"里的坐标
  • 空间规律 :经过海量数据训练,语义相近的词,坐标距离会非常近。例如 AppleBanana 的坐标挨在一起,而离 Car 极远。

这一步,数字 ID 变成了具有"初始语义"的数学实体。

B. 第二步:Transformer 与注意力机制 ------ 动态聚合上下文

这是大模型最核心的"大脑"部分。单个 Token 的向量是静态的,但在不同的句子里,同一个词的意思可能天差地别。

  • 句子 1:Apple is a tasty fruit. (苹果)
  • 句子 2:Apple released a new iPhone. (苹果公司)

Transformer 是如何"转弯"的?

对于开发者来说,你可以把它想象成一个"带有动态权重计算的特征聚合系统":

  1. 并行摄入 (Parallelism)
    模型不像 RNN 那样逐字阅读,它利用矩阵运算一次性读入所有 Token。这就像是启动了并行的单元同时处理整句话,效率极高。
  2. 自注意力机制 (Self-Attention)
    这是 Transformer 的灵魂。每个 Token 都会在"内部总线"上广播自己的需求,并根据相关性从其他 Token 那里拉取特征:
  • 打分 (Scoring) :在句子 2 中,处理 Apple 时,模型计算发现后面的 iPhone 与它关联度极高。
  • 加权融合 (Weighted Sum) :模型会将 iPhone 的特征信息按高权重"融合"到 Apple 的向量中。
  • 结果Apple 的向量发生了空间偏移------从原本偏向"水果"的区域,移动到了"科技公司"的区域。

总结:Transformer 让每个 Token 都能根据上下文,实时演化出最准确的语义表达。

C. 第三步:概率预测 (Next Token Prediction) ------ 生成回答

经过多层 Transformer 的"逻辑加工"后,模型对当前语境有了深刻理解。最后一步,它本质上是一个概率预测机

  1. 投影与归一化 :模型将处理后的复杂向量投影回词表大小的维度,并通过 Softmax 函数,给词表里的每一个 Token 算出一个"胜出概率"。
  2. 采样预测
    例如输入:"我喜欢吃"
    模型计算后输出概率:
  • Token 苹果 (ID 5401): 概率 15%
  • Token 西瓜 (ID 6621): 概率 12%
  • Token 石头 (ID 9912): 概率 0.0001%

最终模型根据概率(结合 Temperature 参数)选中 苹果,这就是我们看到的回答。

写在最后:理解 Token 的工程意义

到这里,你已经构建了一个完整的认知链路:
原始文本BPE 切分Token IDEmbedding 向量Attention 语义聚合概率预测

理解了这一点,你就明白了为什么 Prompt 里的每一个字、每一个空格都会消耗 Token,并且会通过注意力机制影响最终的生成概率。

三、 核心算法:BPE (Byte-Pair Encoding)

目前 GPT-3.5, GPT-4, Llama 等主流模型均主要基于 BPE 算法。它是一种介于"字符级"和"单词级"之间的分词方案。

1. BPE 的直观逻辑

BPE 的核心思想非常简单:统计语料中相邻字符对出现的频率,不断将最频繁出现的"字符对"合并成一个新的"Token",直到达到预设的词表大小。

想象我们要处理语料序列:"hug pug pun bun"

  1. 拆分 :起初全是单个字符(如 h, u, g)。
  2. 统计 :发现 ug 经常挨在一起(hug,pug),un 也经常挨在一起(pun, bun)。
  3. 合并 :假设先合并 u+g。从此 ug 变成了一个不可分割的新单元(Token)。
  4. 循环:在新的基础上继续找下一个最热组合,周而复始。

2. 用 Go 手搓一个 BPE 训练器

作为 Go 开发者,没有什么比看代码更能理解原理了。下面我们用 Go 模拟上述 "hug pug pun bun" 的合并过程。

:为了演示核心逻辑,我们简化了预分词步骤,直接将输入视为一串连续的 ASCII 整数序列。

go 复制代码
package main

import (
	"fmt"
)

// 定义一些基础 ASCII 码,方便阅读
const (
	h = 104; u = 117; g = 103
	p = 112; n = 110; b = 98
	space = 32
)

// getStats: 核心步骤 1 ------ 统计相邻 pair 的频率
func getStats(ids []int) map[[2]int]int {
	counts := make(map[[2]int]int)
	// 滑动窗口遍历:每次看 ids[i] 和 ids[i+1]
	for i := 0; i < len(ids)-1; i++ {
		pair := [2]int{ids[i], ids[i+1]}
		counts[pair]++
	}
	return counts
}

// merge: 核心步骤 2 ------ 执行合并操作
func merge(ids []int, targetPair [2]int, newTokenID int) []int {
	newIds := make([]int, 0, len(ids))
	i := 0
	for i < len(ids) {
		// 贪婪匹配:如果当前位置能组成目标 pair,就合并!
		if i < len(ids)-1 && ids[i] == targetPair[0] && ids[i+1] == targetPair[1] {
			newIds = append(newIds, newTokenID) // 写入新 ID
			i += 2                              // 关键:跳过被合并的两个旧 Token
		} else {
			newIds = append(newIds, ids[i])     // 保持原样
			i++
		}
	}
	return newIds
}

func main() {
	// 模拟语料: "hug pug pun bun"
	tokens := []int{
		h, u, g, space,
		p, u, g, space,
		p, u, n, space,
		b, u, n,
	}

	fmt.Printf("初始序列: %v\n长度: %d\n", tokens, len(tokens))
	fmt.Println("------------------------------------------------")

	// 词表大小设为 256 (ASCII 0-255 已被占用)
	vocabSize := 256 
	numMerges := 2   // 模拟训练 2 轮

	for i := 0; i < numMerges; i++ {
		stats := getStats(tokens)

		// 1. 找到出现频率最高的 Pair
		var bestPair [2]int
		maxCount := 0
		for pair, count := range stats {
			// 注意:Go map 遍历是随机的,如果频率并列,这里选谁全看运气
			if count > maxCount {
				maxCount = count
				bestPair = pair
			}
		}

		if maxCount < 2 {
			fmt.Println("没有频繁出现的组合可合并了")
			break
		}

		// 2. 生成新 Token ID (从 256 开始累加)
		newTokenID := vocabSize + i
		fmt.Printf("Step %d: 发现最热组合 %v (出现 %d 次) -> 合并为新 Token [%d]\n",
			i+1, bestPair, maxCount, newTokenID)

		// 3. 执行全量合并
		tokens = merge(tokens, bestPair, newTokenID)
		fmt.Printf("合并后序列: %v\n", tokens)
		fmt.Println("------------------------------------------------")
	}

	fmt.Printf("最终结果: %v (长度: %d)\n", tokens, len(tokens))
}

3. 代码深度剖析:Go 实现的 3 个亮点

💡 亮点一:为什么 vocabSize 从 256 开始?

你可能注意到了 vocabSize := 256 以及新 Token ID 是 256 + i

  • 基础层 :计算机的底层语言是字节 (Byte),取值范围是 0-255。BPE 算法初始时,将所有文本看作字节流。
  • 扩展层 :BPE 生成的新 Token(如 uging)是概念上的组合,不能和基础字节冲突。因此,新身份证必须从 256 开始发放
  • 演进:随着训练进行,ID 会变成 257, 258... 甚至达到 100,000+(如 GPT-4 的词表大小约 10 万)。
💡 亮点二:Map Key 的玄机 [2]int ------ 从"棋盘坐标"到"字符对"

getStats 函数中,我们使用了 map[[2]int]int。这不仅仅是为了配合 BPE,更是 Go 语言中处理"二维固定关系"的标准范式(Idiom)。

为了理解这一点,我们可以借用游戏开发的场景:

1. 场景类比:棋盘与坐标

想象你在开发一个中国象棋或战棋游戏。棋盘是一个二维网格,你需要存储每个棋子在棋盘上的位置。

  • 错误直觉 :很多新手会想用切片(Slice)[]int{x, y} 来表示坐标。
  • Go 的限制 :Go 语言中,切片包含指针,不可比较,严禁作为 Map 的 Key

2. 正确姿势:使用数组作为坐标

在 Go 中,[2]int(数组)是值类型 ,它就像一个实实在在的"坐标点"。只要 xy 一样,两个数组就相等。这使得它完美适合做 Map 的 Key。

我们可以这样定义棋盘状态:

go 复制代码
// 游戏开发经典场景:稀疏矩阵 / 棋盘状态
// Key: [2]int 代表坐标 {x, y}
// Value: string 代表该位置的棋子
chessboard := make(map[[2]int]string)

// 放置棋子:
// 在坐标 (4, 0) 放一个 "帅"
chessboard[[2]int{4, 0}] = "帅"

// 在坐标 (4, 3) 放一个 "兵"
chessboard[[2]int{4, 3}] = "兵"

// 查找棋子:
pos := [2]int{4, 3}
if piece, ok := chessboard[pos]; ok {
    fmt.Println("在位置", pos, "发现棋子:", piece) // 输出: 发现棋子: 兵
}

3. 回到 BPE 算法

BPE 的逻辑与棋盘完全一致,只是把"空间坐标 "换成了"相邻字符":

  • 棋盘逻辑xy 确定一个位置 -> 对应一个棋子
  • BPE 逻辑CharACharB 确定一个组合 -> 对应一个频率
go 复制代码
// BPE 统计逻辑
// Key: [2]int 代表相邻的一对字符 {CharA, CharB}
// Value: int 代表这对字符出现的次数
stats := make(map[[2]int]int)

// 记录 "u" (117) 和 "g" (103) 这一对
pair := [2]int{117, 103} 
stats[pair]++ 

总结这个 Idiom:

当我们在 Go 中需要把固定数量 (比如 2个或 3个)的简单数据组合起来,作为一个唯一的哈希键(Hash Key )时,数组(Array)是唯一的选择,也是最高效的选择。它避免了定义复杂结构体的麻烦,又绕过了切片不可比较的限制。

💡 亮点三:Merge 函数的"贪婪与跳跃"

merge 函数不仅仅是简单的替换,它体现了 BPE 的两个核心策略:

  1. 全量处理 (Global Scope)
    tokens 是一个一维大数组。merge 操作不区分单词边界,它对整个语料库进行全局扫描和替换 。无论 ug 出现在句首还是句尾,一视同仁。
  2. 贪婪跳跃 (Greedy Skip)
    注意代码中的 i += 2。当检测到 ids[i]ids[i+1] 匹配目标时,我们合成一个新 Token,然后直接跳过这两个旧位置。这保证了已被合并的字符不会再次参与后续的合并(即每个字符在每一轮只能被"吃"一次)。

4. 潜在的挑战:随机性与确定性

在运行上述代码时,你可能会发现一个有趣的现象:ugun 谁先被合并?

  • 现状 :在我们的语料中,ugun 都出现了 2 次(频率并列)。
  • Go 的行为 :Go 语言的 map 遍历顺序是随机的。这意味着在频率相同的情况下(Tie-breaking),程序每次运行可能会选择不同的合并顺序。
  • 工业级做法 :在实际的大模型训练(如 GPT)中,为了保证结果的可复现性,必须消除这种随机性。通常的做法是:将所有 Pair 提取出来,先按频率排序,频率相同时再按 Token ID 大小或字典序排序,确保每次训练得到的词表一模一样。

通过这个简单的 Go 模型,我们不仅跑通了 BPE 的流程,更理解了其背后的数据结构选择与算法权衡。

四、 工程实战:精准计算 Token 与成本控制

理解了 BPE 的原理后,我们在实际工程(如开发 AI 客服、RAG 系统、Agent)中,主要面临两个必须要解决的挑战:

  1. 省钱(Cost Estimation):API 是按 Token 收费的,且计费规则比想象中复杂,不能等几千美元的账单来了才后知后觉。
  2. 不报错(Context Management) :每个模型都有上下文窗口限制(如 4k, 8k, 128k)。如果提示词太长,API 会直接返回 400 Bad Request

本章将提供全套的 Go 语言解决方案。

1. 为什么不能用 len(string)

很多初学者习惯用字符串长度或空格分割来估算 Token,这是极其危险的。Token 数量与字符长度没有简单的线性关系:

  • 英文Hello world (11字符) -> 2 Tokens。
  • 中文你好世界 (12字节) -> 可能会被编码为 2~4 个 Token,取决于模型词表。
  • 代码:大量的缩进空格、换行符都会消耗 Token。

结论你必须使用与模型完全一致的 Tokenizer 进行计算。

2. 实战:使用 Go 计算 OpenAI Token

针对 OpenAI 的模型(GPT-3.5, GPT-4, Embedding 等),官方推荐使用 tiktoken。在 Go 语言中,我们使用社区维护的高性能移植版 tiktoken-go

安装依赖:

bash 复制代码
go get github.com/pkoukk/tiktoken-go

代码示例:计算 Token 数量

go 复制代码
package main

import (
	"fmt"
	"log"

	"github.com/pkoukk/tiktoken-go"
)

func main() {
	text := "Go语言是构建AI应用的最佳选择!"

	// 1. 获取特定模型的编码器 (Encoding)
	// GPT-4, GPT-3.5-Turbo, Text-Embedding-3 均使用 "cl100k_base"
	tkm, err := tiktoken.EncodingForModel("gpt-4")
	if err != nil {
		log.Fatalf("getEncoding: %v", err)
	}

	// 2. 编码 (Encode): 将文本转换为 Token ID 列表
	tokenIDs := tkm.Encode(text, nil, nil)

	// 3. 统计数量
	fmt.Printf("原文: %s\n", text)
	fmt.Printf("Token 数: %d\n", len(tokenIDs))
	fmt.Printf("Token IDs: %v\n", tokenIDs)
}

如果你想直观看到一段话会被切成什么样,推荐去 OpenAI 官网的 Tokenizer 游览器点点看。你会发现,同样的词,大写首字母和全小写,Token ID 往往是完全不同的。

3. 高频场景:如何安全地截断文本?

在 RAG(Retrieval-Augmented Generation,检索增强生成)应用中,检索出的文档经常会撑爆模型的上下文窗口。此时,不能直接用字符串切片 text[:1000] 进行截断,否则可能导致中文乱码(切断了多字节字符)或破坏 BPE 语义(切断了单词)。

标准做法:Encode -> Slice IDs -> Decode

go 复制代码
// SafeTruncate 按照 Token 数量限制安全截断文本
func SafeTruncate(text string, maxTokens int, model string) (string, error) {
	tkm, err := tiktoken.EncodingForModel(model)
	if err != nil {
		return "", err
	}

	// 1. 转成 Token IDs
	tokens := tkm.Encode(text, nil, nil)

	// 2. 检查是否需要截断
	if len(tokens) <= maxTokens {
		return text, nil
	}

	// 3. 截取前 maxTokens 个 ID
	truncatedTokens := tokens[:maxTokens]

	// 4. 解码回字符串 (Decode)
	// tiktoken 会自动处理好边界,保证不会出现乱码字符
	return tkm.Decode(truncatedTokens), nil
}

4. 开源模型(Llama, Mistral 等)的处理

非 OpenAI 模型的词表与 GPT 不同。对于 Llama 3、Mistral 等开源模型,通常需要加载其特定的 tokenizer.json 文件。

在 Go 中,推荐使用 HuggingFace Tokenizers 的绑定库(如 github.com/daulet/tokenizers)进行处理。

5. 避坑指南:大模型的计费机制与"上下文爆炸"

这是开发者最容易踩坑的地方。大模型的计费公式通常为:
Total Cost=(Input Tokens×Pin)+(Output Tokens×Pout) \text{Total Cost} = (\text{Input Tokens} \times P_{in}) + (\text{Output Tokens} \times P_{out}) Total Cost=(Input Tokens×Pin)+(Output Tokens×Pout)

这里有三个必须注意的隐形成本:

A. 输出比输入贵

通常 Output Token 的单价是 Input 的 3~10 倍

  • 这意味着:让模型"读"一本书很便宜,但让模型"写"一本书非常贵。

B. 多轮对话的"滚雪球"效应 (The Rolling Snowball)

大模型 API 是无状态的。为了保持对话连贯,你必须在第 N 轮请求时,把前 N-1 轮的历史记录全部发回去。

推演场景

  1. 第1轮:你发 "Hi" (2 tokens)。付费:2 input。
  2. 第2轮 :模型回复了 50 tokens。你又问了 5 tokens。
    • 你实际发送的 Input 是:"Hi" + 模型回复 + 新问题
    • 付费:(2 + 50 + 5) = 57 tokens input。
  3. 第3轮:...
  4. 第10轮:你可能只发了一个词,但你需要为前 9 轮所有的历史记录再次付费。

这就是为什么长对话聊久了,费用会呈线性甚至指数级上升。

C. System Prompt 的"入场费"

你设置的 System Prompt(如"你是一个专业的代码助手...")在每一轮对话中都会被发送。如果 System Prompt 很长(比如 2k tokens),那么用户每说一句话,你都要先付这 2k tokens 的基础费用。

D. 视觉盲区

很多模型对控制字符(如换行符 \n、制表符 \t)计费非常狠。在处理代码或格式化文档时,1个缩进可能就消耗了 1 个 Token。这在写大型 Prompt 时是需要优化的细节。

6. 成本预估代码实现

基于上述机制,后端应该实现一个成本预估器:

go 复制代码
type CostEstimator struct {
	InputPricePer1k  float64 // 例如 0.0025
	OutputPricePer1k float64 // 例如 0.0100 (通常更贵)
}

// Estimate 计算单次请求的预估成本
// history: 历史对话内容
// newPrompt: 用户当前问题
// estimatedOutputLen: 预估模型回答的长度(可基于经验设定,如 500)
func (c *CostEstimator) Estimate(history []string, newPrompt string, estimatedOutputLen int) float64 {
	tkm, _ := tiktoken.EncodingForModel("gpt-4")
	
	// 1. 计算 Input Tokens (包含历史记录 + 新问题 + System Prompt)
	totalInputText := ""
	for _, msg := range history {
		totalInputText += msg
	}
	totalInputText += newPrompt
	
	inputTokens := len(tkm.Encode(totalInputText, nil, nil))
	
	// 2. 计算费用
	inputCost := (float64(inputTokens) / 1000.0) * c.InputPricePer1k
	outputCost := (float64(estimatedOutputLen) / 1000.0) * c.OutputPricePer1k
	
	return inputCost + outputCost
}

通过这套组合拳------精准计算、安全截断、透视成本------你就能构建出一个既健壮又经济的 AI 应用。

五、 结语:从"调包侠"进阶为"AI 架构师"

至此,我们完成了对 Token 的全方位拆解。

从最基础的"Token ≠\neq= 单词"概念纠偏,到亲手用 Go 语言实现 BPE 算法的贪婪合并逻辑,再到工程实战中对 API 成本与上下文窗口的精准控制。你应该能感受到,AI 开发不仅仅是写好 Prompt 那么简单,背后隐藏着大量的工程细节与算法权衡。

在 Python 主导模型训练的当下,Go 语言 凭借其高并发、强类型和极致的性能,正在 AI Infra(AI 基础设施) 领域发挥着越来越重要的作用。无论是构建高性能的 API 网关、实时的计费系统,还是高吞吐的 RAG 检索服务,理解 Token 这一最基本的"原子单位",都是我们构建健壮系统的基石。

当别人还在因"上下文溢出"而报错,或者因看不懂账单而焦虑时,掌握了底层逻辑的你,已经懂得如何用 SafeTruncate 优雅降级,用 CostEstimator 精打细算。

这就是"调包"与"工程"的区别。

思考题:既然中文 Token 普遍比英文贵,如果你在做一个面向全球的 RAG 系统,你会为了省钱而强制要求模型内部只用英文思考,最后再翻译回中文吗?这种做法会有什么'工程代价'?

相关推荐
QYR_112 小时前
汽车 ABS 和 ESC 系统市场全景调研报告(2026-2032):规模、技术迭代与竞争格局
大数据·人工智能
碎碎思2 小时前
使用 Arm Cortex-M1 实现低成本图像处理系统 的 FPGA 方案详解
arm开发·图像处理·人工智能·fpga开发
liu****2 小时前
神经网络基础
人工智能·深度学习·神经网络·算法·数据挖掘·回归
Aaron15882 小时前
基于RFSOC 49DR+VU13P的64通道VPX架构波束成形技术分析
c语言·人工智能·算法·架构·信息与通信·信号处理·基带工程
得一录2 小时前
大模型的基本概念及主要功能
人工智能·aigc
雨大王5122 小时前
如何利用工业制造智能体实现汽车生产的全链路协同优化?
大数据·人工智能·汽车·制造
雨大王5122 小时前
实时质量监控如何通过数据驱动优化汽车生产质量?
大数据·人工智能·汽车·制造
筱昕~呀2 小时前
“烷”域天观——甲烷监测系统
人工智能·python·深度学习·豆包
行业探路者2 小时前
如何通过音频二维码生成提升信息分享效率?
大数据·人工智能·学习·二维码·产品介绍