自然语言处理实战:从词向量到Transformer的工程实践解析

说句实话,市面上讲自然语言处理的书不少,但真正能让开发者上手把项目跑起来、把代码写进生产环境的并不多。《自然语言处理实战第二版(MEAP)(二)》这本书我从第一版的纸质版一直跟到第二版的早期访问章节,最大的感受是,这一版并不是简单修修补补,而是把整个技术思路从“规则+统计”彻底切换到了“向量化+深度学习+预训练模型”这条主线上。如果你正卡在词向量、Transformer、文本分类这类环节,读完第二部分基本能把关键链路串起来。

先说清楚这本书适合谁。你不是搞理论研究的,也不是刚摸Python的小白,而是已经有一些Python基础、处理过简单文本数据、想系统掌握NLP工程化套路的开发者。第二部分正好落在全书最核心的地带:从文本如何变成向量,到神经网络如何吃进这些向量,再到如何用现代预训练模型解决真实任务。这个位置卡得很有意思,往前承接文本清洗和基础特征工程,往后衔接微调、部署和模型调优。所以这一部分读透,等于打通了NLP项目的“任督二脉”。

1. 内容整体设计与思路拆解

1.1 为什么第二版要重新设计内容主线

第一版的时代背景还是词袋模型、TF-IDF和Word2Vec三分天下,那时候做文本分类,能调个gensim训练词向量已经算很厉害了。但今天的NLP生态已经被Transformer架构重塑,Embedding不再是单独的词向量,而是上下文相关的动态表示。第二版把重心移过来,其实是顺应了工业界的真实需求:你进任何一家做文本业务的公司,看到的不会是手写TF-IDF逻辑,而是加载一个预训练模型做微调,或者直接用向量数据库做语义检索。

MEAP版本(Manning Early Access Program)的节奏是分章节放出,读者边读边反馈。第二部分继续早期的章节,重点是把“文本表示”这件事讲透。作者没有一上来就塞一个巨大的Transformer结构图,而是先从最朴素的向量化手段讲起,再一步步引出注意力机制。这种设计的好处是,当你最终看到BERT或GPT结构时,能理解每一层到底在做什么,而不是把模型当成黑盒。

1.2 从“文本即序列”到“文本即向量”的思维转换

传统开发者的直觉是,文本处理就是字符串处理,正则、分词、停用词、词性标注。但深度学习的核心前提是,一切输入必须是数值张量。这里的翻译过程并不只是查表,而是要把语义关系编码进向量空间。第二部分花了不少篇幅解释这个转换是怎么发生的。我的理解是,它其实做了三件事:把离散的词汇映射成稠密向量,把词序信息通过位置编码保留,把上下文信息通过多层变换融合。

这三个步骤每一步都有坑。稠密向量的维度选择、位置编码的方式、上下文融合的层数,都会直接影响下游效果。书中给的实验截图和对比表格,能很直观看到同一个任务在不同表示方法下的差异。这对初学者特别有价值,因为只看理论永远不知道维度从50调到300到底差多少,也不知道为什么有时候LayerNorm比BatchNorm更稳。

1.3 实战项目的选择逻辑

第二部分的实战项目编排也不是随意的。它选的任务都是NLP里最典型的几种:文本分类、命名实体识别、文本相似度计算。这三个任务覆盖了大部分业务场景:客服工单分类、合同关键信息抽取、搜索推荐系统的语义匹配。你会发现它没选机器翻译或问答这种大而重的任务,因为那些任务工程成本太高,放在这个位置容易劝退读者。相反,用三个基础任务把核心模型跑通,后面再去扩展其他任务就顺理成章了。

2. 核心细节解析与实操要点

2.1 词嵌入的训练与加载细节

第二部分里对Word2Vec和GloVe的讲解没有停留在“这两个都是词嵌入”的层面,而是仔细区分了它们的训练目标和适用场景。Word2Vec用的是局部上下文窗口,GloVe用的是全局共现统计。实操中你会发现,在中小规模语料上,Word2Vec的skip-gram往往比CBOW更能捕捉罕见词的语义;但如果你的语料够大,GloVe的训练速度优势也会体现出来。

这里我建议你亲手做一次对比实验:拿同一批新闻语料,分别训练两种嵌入,然后用一个简单的KNN或者余弦相似度去查“苹果”的近义词。你会发现Word2Vec给出的可能是“梨”“水果”,GloVe给出的可能更偏向“公司”“手机”。这就是不同训练目标和语料分布带来的实际差异。不要迷信哪个模型更先进,关键看你的下游任务需要什么类型的相似度。

加载预训练嵌入时有一个常见坑:词表对齐。如果你用的是官方发布的GloVe文件,注意它的第一行是“词数 维度”,而一些第三方转换格式没有这一行。加载时要判断并跳过。另外,Embedding矩阵的初始化方式也很重要,通常用均匀分布或正态分布,方差控制在0.1以内,不然训练初期梯度很容易爆炸。

2.2 上下文嵌入:从静态向量到动态向量

静态词嵌入的最大问题是多义词。比如“苹果”这个词,在“吃苹果”和“苹果公司”里应该是完全不同的语义,但静态词嵌入只有一个向量。第二部分用了一个很清晰的例子来说明这个问题,然后自然引入ELMo和BERT这类基于上下文的模型。ELMo的思路是训练一个双向语言模型,把每一层的隐状态拼起来作为词向量;BERT则是通过Transformer的注意力机制,让每个token的表示融合整个句子的信息。

实操上,使用这些模型的方式已经从“自己训练”变成了“加载预训练权重”。你要做的不是从零跑一个BERT,而是学会用HuggingFace的接口把模型加载进来,在你自己的数据上做微调。这里需要特别注意输入格式:tokenizer输出的input_ids和attention_mask必须对齐,padding时要用pad_token_id,不要用0硬凑,否则模型会混淆真实内容和填充内容。

2.3 注意力机制到底在算什么

第二部分对注意力机制的解释非常“工程师友好”。它没有用一大堆矩阵公式轰炸你,而是把注意力解释成“加权求和”:每个token都向序列中其他token发起查询,其他token根据相关程度返回权重,然后按权重融合信息。这个机制解决了RNN长距离依赖丢失的问题,也让并行计算成为可能。

我在实践中体会最深的是,注意力可视化是调试模型的好工具。当你把BERT某一层的attention matrix画出来,能看到句子里哪些词建立了强关联。比如在“这家餐厅的菜很好吃,但服务很差”里,模型大概率会把“但”和“服务”“差”关联起来。这能帮你判断模型是否学到了关键语义,而不仅仅是过拟合训练集。

3. 实操过程与核心环节实现

3.1 环境准备与依赖安装

开始实操前,先把环境整理好。我的建议是用Python 3.10+,深度学习框架选PyTorch,版本不要追最新,稳定就好。核心依赖包括transformers、datasets、tokenizers、scikit-learn、pandas。安装命令很简单:

pip install transformers datasets tokenizers scikit-learn pandas torch

如果你的机器有NVIDIA GPU,记得提前装好对应版本的CUDA驱动和PyTorch轮子。没有GPU也能跑,只是BERT类模型的训练速度会很感人。我试过在纯CPU上微调一个小型BERT做情感分类,一个epoch要跑几个小时,而同样的工作在消费级GPU上只需要十几分钟。所以能开GPU就开GPU,哪怕是用一些免费的云端环境也行。

3.2 数据准备与预处理流程

那本书第二部分给了一个完整的文本分类流程,我从自己的经验出发,把预处理步骤简化并固化成一套通用流程。第一步是原始文本清洗,这一步视数据质量而定。如果是爬虫拿到的网页文本,要清HTML标签、去重、处理乱码;如果是社交平台短文本,要处理表情符号和URL。清洗的原则是“最小必要”,不要过度清洗把语义信息也删了。

第二步是切分数据集。不要只用train_test_split随机切,对于时间敏感的文本数据要按时间顺序切,否则会出现时间穿越问题。比如你要预测某个事件是否发生,用过去的数据训练、未来的数据测试才有意义。书中使用的datasets库也支持按比例切分,但你需要确认数据是否已经被打乱过。

第三步是分词和编码。这里是新手最容易出错的地方。HuggingFace的AutoTokenizer会根据模型词表自动选择分词方式,比如BERT用WordPiece,GPT用BPE。你必须使用和模型训练时一致的分词器,不能用自己写的jieba分词结果直接喂给BERT,那样词表对不上,效果会断崖式下跌。正确的做法是:

from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese") text = "自然语言处理实战是一本好书" inputs = tokenizer(text, max_length=128, truncation=True, padding="max_length", return_tensors="pt")

注意这里的max_length不要拍脑袋选,要看你的语料长度分布。我通常先统计所有样本的token长度,取90分位数作为max_length,这样既能覆盖绝大多数样本,又不会因为padding太多浪费计算资源。

3.3 微调一个文本分类模型

微调和从零训练的最大区别是学习率。预训练模型已经有很强的特征表达能力,你只需要用很小的学习率去适配下游任务。书中推荐的AdamW配合线性衰减调度是标准配置。以BERT分类为例,完整训练代码如下:

from transformers import AutoModelForSequenceClassification, Trainer, TrainingArguments model = AutoModelForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=2) training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=16, per_device_eval_batch_size=64, num_train_epochs=3, weight_decay=0.01, save_total_limit=2, load_best_model_at_end=True, metric_for_best_model="accuracy", ) trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer, ) trainer.train()

这段代码里有几个细节值得说。learning_rate用了2e-5,这是BERT微调的标准经验值,太大会破坏预训练权重,太小收敛又慢。batch_size要看显存,16是我在8GB显存下的经验值,如果你的卡更大可以往上调。weight_decay=0.01能抑制过拟合,但不要对所有参数一刀切,一般对LayerNorm层不设衰减。

训练完成后,不要只看准确率。对分类任务还要看精确率、召回率和F1,尤其在类别不平衡的情况下。我记得之前处理一个工单分类数据集,正负样本比是1:9,训练时准确率99%,但正样本召回率是0,模型把所有样本都预测成负类了。所以在书中代码基础上加上分类报告:

from sklearn.metrics import classification_report preds = trainer.predict(eval_dataset).predictions.argmax(-1) labels = eval_dataset["labels"] print(classification_report(labels, preds, target_names=["neg", "pos"]))

3.4 构建一个语义相似度计算流程

第二部分除了分类,还有一个让我留下深刻印象的内容,就是文本相似度。它讲解了三种层次的做法:基于TF-IDF的向量相似度,基于词向量的平均池化相似度,以及基于Sentence-BERT的句子嵌入相似度。三种做法适用场景不同,性能差异也很大。

TF-IDF向量相似度的优点是简单快速,适合关键词匹配场景,比如重复问题检测。词向量平均池化能稍微捕捉语义信息,但会把词序信息完全丢掉,“我打你”和“你打我”平均池化后向量几乎一样,这显然不合理。Sentence-BERT则是专门为句子级相似度设计的模型,它用孪生网络结构让语义相似的句子在向量空间里靠近。

实操中,加载Sentence-BERT并不难:

from sentence_transformers import SentenceTransformer model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2") sentences = ["这家餐厅的菜很好吃", "这家店的食物味道不错"] embeddings = model.encode(sentences) similarity = embeddings[0] @ embeddings[1].T

但你要注意,预训练模型面向的语域和你的业务语域可能有偏差。比如这个多语言模型在通用句子上表现不错,但在医疗文本上效果就差很多。这时候可以收集一批你自己的句子对,做持续训练(contrastive learning),让模型适应你的数据分布。书中也提到了这个思路,代码量不大,但收益明显。

4. 常见问题与排查技巧实录

4.1 训练过程中loss不下降

这是最常见的坑。排查思路按照下面这个顺序走,基本能定位90%的问题。

先看数据是否有问题。标签是否从0开始编号?标签是否和文本一一对应?文本有没有大量空值和重复值?我遇到过一次,因为数据清洗时把换行符删错,导致两行文本黏在一起,模型完全学不到有效信息。把预处理结果print出来人工看一遍,比什么都有效。

再看模型输出层。回归任务用回归头,分类任务用分类头,输出维度对不对?多标签任务要用sigmoid,不能用softmax,否则每个样本所有标签概率加起来等于1,模型没法独立预测每个标签。

再看学习率。如果是自己设计的网络从零训练,学习率可以设到1e-3级别;如果是微调预训练模型,学习率最好在1e-5到3e-5之间。loss剧烈震荡说明学习率太大,loss缓慢爬升说明梯度方向有问题,可能是学习率太小或者数据存在冲突。

最后看是否加载了正确的预训练权重。很多人用transformers加载模型时,model_name和tokenizer_name不一致,或者torch_dtype设置不对,导致推理和训练行为不一致。这个问题特别隐蔽,排查起来很费时间。

4.2 显存不够用

BERT类模型吃显存是出了名的。如果你的显卡只有6GB或8GB,训练batch_size往往要被压到4甚至2。这时候有几个变通方法。

优化器层面,可以用Adafactor替代AdamW,它能大幅减少优化器状态占用的显存。模型层面,启用gradient_checkpointing可以牺牲少量训练时间换取显存空间。方法层面,使用混合精度训练,在PyTorch里就是一行代码的事:

training_args = TrainingArguments(fp16=True)

数据层面,把序列长度从512截断到128或64,显存占用成倍下降。如果业务场景本身不依赖长文本,这招非常有效。我在处理短文本分类任务时,把max_length从512改成128,显存占用直接降到原来的三分之一,而准确率几乎没有变化。

如果这些都不够,还有最后一招:用模型蒸馏。先训练一个大模型,然后用大模型在无标签数据上生成软标签,再拿软标签训练一个小模型。实际效果是,小模型能保留大模型80%以上的性能,但占用资源不到十分之一。

4.3 tokenizer输出维度不一致

这是跑实操时最容易碰到的问题。训练阶段,你通过padding="max_length"把所有样本固定到相同长度,一切都正常。但到了推理阶段,你只对一条文本调用tokenizer,忘了加padding,结果输入维度变成了[1, seq_len],模型还能跑,但不报错的结果往往在性能上打折扣。

解决方案是,在推理阶段也保持和训练时完全一致的tokenizer配置。统一封装一个预处理函数:

def encode(texts, max_length=128): return tokenizer(texts, max_length=max_length, truncation=True, padding="max_length", return_tensors="pt")

使用同一个函数处理训练集和推理输入,就能从根本上避免维度错乱。另外,attention_mask也别忘了带上,你见过不少人只传input_ids,结果模型在padding位置计算了注意力,效果自然不对。

4.4 检查点恢复与随机种子

长时间训练时,一般会设置save_total_limit和load_best_model_at_end。但有个细节:恢复训练时,Trainer的resume_from_checkpoint参数必须指向一个完整的checkpoint目录,里面要有model、optimizer、scheduler状态,不是只有模型权重。

如果你的数据集很小,只有几千条样本,建议固定随机种子,否则不同运行之间结果方差太大,你都没法判断模型改动到底有没有效果。固定种子要同时设PyTorch和Python的:

import torch import random import numpy as np def set_seed(seed): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)

这样做不是为了让结果绝对可复现(GPU并行计算本身很难完全复现),而是为了让你在调试时能相对公平地对比版本效果。

5. 进阶方向与实际项目扩展

5.1 实体识别任务的微调差异

第二部分以分类任务为主,但它也铺垫了序列标注任务。命名实体识别(NER)和分类最大的区别是,它要为每个token预测标签,而不是给整个序列一个标签。所以模型的输出层是每个token对应一个类别分布,评估方式也从准确率变成了实体级别的精确率和召回率。

你如果要从分类任务迁移到NER,只需要改两部分:数据集标签改成BIO格式,模型换成AutoModelForTokenClassification,num_labels改成标签数。损失函数会自动计算token级别的交叉熵。但要注意padding部分的标签通常设为-100,这样计算loss时会被自动忽略,这是HuggingFace的一个约定。

5.2 检索增强生成与向量数据库

如果你顺着第二部分的向量化思路再往前走一步,就会来到检索增强生成(RAG)的地盘。前半部分学到的文本向量化、相似度计算,正好是RAG系统的基石。你可以把文档库切块后向量化存入向量数据库,用户提问时先把问题向量化,检索出最相关的文档片段,再把这些片段拼进提示词,交给大模型生成回答。

这一步尤其适合企业内部知识库问答,它不需要微调大模型,也能让回答带上你自有数据的依据。书中虽然没有完整展开RAG,但你在读完第二部分后,再去接触RAG会非常轻松,因为核心概念你已经全掌握了。

5.3 模型部署时的量化与裁剪

训练完的模型要上生产环境,一般会做一步量化。用PyTorch的量化接口或者Transformers的bitsandbytes库,把模型从FP16压缩到INT8甚至INT4,显存占用和推理延迟都能显著下降。代价是推理精度略有损失,但对大多数文本任务来说,损失在可控范围内。

如果你的模型要部署在CPU上,那就更推荐量化了。一个BERT-base模型FP32版本大概400MB,量化到INT8只有100MB出头,推理速度快了3到5倍。对于延迟敏感的业务,这个优化几乎是必做的。

6. 读这本书时的学习建议

第二部分的知识密度较高,一天读一章并做完所有练习是比较现实的节奏。不要只看代码,一定要动手改参数。比如把batch_size从8改成32,观察显存变化;把padding策略改成动态padding,观察训练速度变化。只有亲手改过,才能理解这些参数为什么存在。

遇到不懂的概念,比如多头注意力里的QKV,建议配合可视化工具一起看。你可以在HuggingFace上找一些现成的注意力可视化脚本,拿一句中文输入进去,看模型内部发生了什么。看完再回来看书里的公式,理解会拔高一个层次。

说实话,这本书第二部分的内容放在今天依然非常有价值。原因很简单:不管底层模型怎么升级,文本嵌入、上下文建模、微调训练、相似度匹配这些核心范式没有变。你把这一部分吃透了,往后看任何新模型,都只是在“文本到向量”的框架里换更优的编码器而已。这也是我为什么愿意持续关注这本MEAP版本的更新,因为每一章放出来,都等于一次把最新工程经验融入经典框架的机会。

相关新闻

从DOOM到自动化测试:强化学习决策模型的迁移实战

从DOOM到自动化测试:强化学习决策模型的迁移实战

一个 AI Agent 如果只会在模拟环境里刷高分,那它离"能用"还有很远。真正的考验是:把它放进一个没见过的场景,它还能不能根据有限的信息,做出对的决策。我最近把一个原本训练在 DOOM 风格对抗环境上的决策模型 Jev&#…

2026/10/22 9:59:14 阅读更多 →
PostgreSQL底层故障排查:pageinspect工具实战详解

PostgreSQL底层故障排查:pageinspect工具实战详解

前阵子碰到一个挺闹心的故障:某张业务表的容量持续上涨,磁盘告警都触发了,可业务写入量并没有明显增加。跑了一遍VACUUM,空间也纹丝不动。我用常规的pg_stat_user_tables、pg_stat_progress_vacuum查了一圈,都看不出名…

2026/10/21 7:55:10 阅读更多 →
Playwright MCP:AI驱动的浏览器自动化与跨平台测试

Playwright MCP:AI驱动的浏览器自动化与跨平台测试

这两年做Web自动化测试,我从早期的录制回放工具一路换到代码级框架,老实说,真正让我觉得"工具终于跟上人了"的节点,是Playwright MCP这套组合出现之后。以前写一条跨平台测试用例,要先关心浏览器驱动、等待时…

2026/10/22 9:59:19 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/21 9:32:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/21 9:31:32 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →