采样过程源码解析:从 logits 到 token 的采样策略

采样过程源码解析:从 logits 到 token 的采样策略

在自然语言处理(NLP)领域,尤其是生成式模型中,采样过程是将模型输出的 logits 转换为实际可读的 token 的关键步骤。这一过程不仅决定了生成文本的多样性,还影响着模型输出的质量和实用性。本文将深入解析采样过程的源码实现,探讨从 logits 到 token 的多种采样策略,帮助读者更好地理解这一核心环节。

1. Logits 的生成与理解

在深度学习模型中,尤其是基于 Transformer 的架构,模型的最后一层通常会输出一个形状为 (batch_size, sequence_length, vocab_size) 的张量,其中 vocab_size 是词汇表的大小。这个张量中的每个值,我们称之为 logits,代表了模型对每个位置上每个可能 token 的预测分数。

Logits 本身并不直接代表概率,它们需要通过 softmax 函数进行归一化,转换为概率分布。然而,在采样过程中,我们并不总是直接使用 softmax 后的概率,而是基于 logits 应用各种采样策略,以平衡生成文本的准确性和多样性。

2. 采样策略概览

采样策略的选择直接影响生成文本的质量。常见的采样策略包括贪婪采样(Greedy Sampling)、随机采样(Random Sampling)、温度采样(Temperature Sampling)、Top-k 采样(Top-k Sampling)和 Top-p(Nucleus)采样(Top-p Sampling)。下面,我们将逐一解析这些策略的源码实现。

2.1 贪婪采样

贪婪采样是最简单的采样策略,它选择每个位置上概率最高的 token 作为输出。虽然这种方法能保证生成文本的确定性,但往往缺乏多样性,容易陷入重复或模式化的输出。

import torch import torch.nn.functional as F defgreedy_sample(logits):# 应用 softmax 获取概率分布 probs = F.softmax(logits, dim=-1)# 选择每个位置上概率最高的 token _, sampled_tokens = torch.max(probs, dim=-1)return sampled_tokens 

2.2 随机采样

随机采样,也称为多项式采样,根据 softmax 后的概率分布随机选择 token。这种方法能增加输出的多样性,但也可能导致生成不连贯或无意义的文本。

defrandom_sample(logits): probs = F.softmax(logits, dim=-1)# 根据概率分布随机采样 sampled_tokens = torch.multinomial(probs, num_samples=1).squeeze(-1)return sampled_tokens 

2.3 温度采样

温度采样通过调整 softmax 函数的“温度”参数来控制输出的多样性。温度参数 T 越大,概率分布越平滑,采样结果越多样;T 越小,概率分布越尖锐,采样结果越接近贪婪采样。

deftemperature_sample(logits, temperature=1.0):# 调整 logits 的“温度” adjusted_logits = logits / temperature probs = F.softmax(adjusted_logits, dim=-1) sampled_tokens = torch.multinomial(probs, num_samples=1).squeeze(-1)return sampled_tokens 

2.4 Top-k 采样

Top-k 采样限制了采样的范围,只从概率最高的 k 个 token 中进行选择。这种方法能在保证一定多样性的同时,避免选择到概率极低、可能不合理的 token。

deftop_k_sample(logits, k=10): probs = F.softmax(logits, dim=-1)# 获取概率最高的 k 个 token 的索引 top_k_probs, top_k_indices = torch.topk(probs, k=k, dim=-1)# 重新归一化 top-k 概率 top_k_probs /= top_k_probs.sum(dim=-1, keepdim=True)# 从 top-k token 中随机采样 sampled_tokens = torch.multinomial(top_k_probs, num_samples=1).squeeze(-1)# 将采样到的索引映射回原始 token# 注意:这里需要额外的步骤来获取实际 token,简化示例中省略return sampled_tokens # 实际实现中需处理索引映射

2.5 Top-p(Nucleus)采样

Top-p 采样,也称为 Nucleus 采样,是一种更灵活的采样策略。它选择概率累积和超过预设阈值 p 的最小 token 集合,然后在这个集合中进行随机采样。这种方法能自适应地调整采样范围,既保证了多样性,又避免了低概率 token 的干扰。

deftop_p_sample(logits, p=0.9): probs = F.softmax(logits, dim=-1) sorted_probs, sorted_indices = torch.sort(probs, descending=True) cumulative_probs = torch.cumsum(sorted_probs, dim=-1)# 找到满足累积概率 >= p 的最小索引 mask = cumulative_probs < p # 在满足条件的 token 中随机采样# 注意:这里需要处理边界情况,简化示例中省略# 实际应用中,可能需要更复杂的逻辑来确保至少选择一个 token selected_indices = sorted_indices[mask] selected_probs = sorted_probs[mask]# 重新归一化选中的概率 selected_probs /= selected_probs.sum(dim=-1, keepdim=True) sampled_tokens = torch.multinomial(selected_probs, num_samples=1).squeeze(-1)# 将采样到的索引映射回原始 token# 注意:这里需要额外的步骤来获取实际 token,简化示例中省略return sampled_tokens # 实际实现中需处理索引映射

3. 结论

采样过程是自然语言生成模型中的关键环节,它直接决定了生成文本的质量和多样性。从简单的贪婪采样到复杂的 Top-p 采样,每种策略都有其独特的优势和适用场景。在实际应用中,我们往往需要根据具体任务的需求,灵活选择或组合这些采样策略,以达到最佳的生成效果。

通过深入解析这些采样策略的源码实现,我们不仅能更好地理解它们的工作原理,还能为模型优化和定制提供有力的支持。希望本文能为读者在自然语言生成领域的探索提供有益的参考。

Read more

5分钟精通llama-cpp-python:从安装到AI应用实战全解析

5分钟精通llama-cpp-python:从安装到AI应用实战全解析 【免费下载链接】llama-cpp-pythonPython bindings for llama.cpp 项目地址: https://gitcode.com/gh_mirrors/ll/llama-cpp-python 想要在个人电脑上轻松运行大语言模型?llama-cpp-python作为专为开发者设计的Python绑定库,为您提供了一条快速接入llama.cpp推理引擎的便捷通道。本指南将带您深入掌握这个强大的AI工具包,从基础安装到高级功能应用,一站式解决所有技术难题!🚀 🎯 环境准备与系统兼容性 在开始安装llama-cpp-python之前,请确保您的环境满足以下要求: 基础环境配置: * Python 3.8或更高版本 * C编译器(Linux:gcc/clang,Windows:Visual Studio/Mingw,MacOS:Xcode) * 充足的内存和存储空间 平台特定注意事项: * Windows用户:建议使用Visual Studio构建工具 * MacO

By Ne0inhk

【2026大模型面试圣经】(2)主流大模型架构全景 | GPT/LLaMA/DeepSeek/Qwen深度对比

2026大模型面试圣经(2):主流大模型架构全景 | GPT/LLaMA/DeepSeek/Qwen深度对比 定位:了解每个主流模型"怎么设计的、为什么这样设计",面试中不只说出名字,还能对比分析。 目标:看完本章,你能画出GPT/LLaMA/DeepSeek的架构图,说清每个设计选择背后的权衡。 模块一:GPT系列架构演进 | 从GPT-1到GPT-4 1.1 核心概念 什么是GPT? GPT(Generative Pre-trained Transformer)是OpenAI推出的系列模型,核心思想是"在大量文本上做自回归预训练,然后通过prompt引导做各种任务"。 GPT-1(2018):首次证明"预训练+微调"在NLP上的威力。12层Transformer Decoder,117M参数。用BookCorpus做CLM预训练。

By Ne0inhk
一文看懂:AI编程工具深度对比:Cursor、Copilot、Trae与Claude Code

一文看懂:AI编程工具深度对比:Cursor、Copilot、Trae与Claude Code

AI编程工具深度对比:Cursor、Copilot、Trae与Claude Code 引言 在人工智能技术蓬勃发展的今天,AI编程工具已成为开发者提高效率的重要助手。从早期的代码补全插件到如今能够理解整个代码库的智能助手,AI编程工具正在不断进化。本文将对当前主流的AI编程工具——Cursor、GitHub Copilot、Trae和Claude Code进行全面对比,帮助开发者选择最适合自己的工具。 主流AI编程工具概述 Cursor Cursor是一款基于VSCode的AI驱动代码编辑器,它最大的特点是能够理解整个代码库的上下文,提供智能的代码补全和重构建议。Cursor默认使用Claude-3.5-Sonnet模型,即使是OpenAI投资的公司,也选择了Claude模型作为默认选项,这足以说明其在代码生成领域的优势。 GitHub Copilot GitHub Copilot是由GitHub与OpenAI合作开发的AI编码助手,集成在VSCode、Visual Studio等主流编辑器中。它基于OpenAI的模型,能够根据注释和上下文自动生成代码,是AI编程工具

By Ne0inhk

llama.cpp量化模型部署实战:从模型转换到API服务

1. 为什么你需要关注llama.cpp:让大模型在普通电脑上跑起来 如果你对AI大模型感兴趣,肯定听说过动辄需要几十GB显存的“庞然大物”。想在自己的电脑上跑一个7B参数的模型,以前可能得配一张昂贵的专业显卡。但现在,情况不一样了。我今天要跟你聊的 llama.cpp,就是那个能让大模型“瘦身”并飞入寻常百姓家的神奇工具。 简单来说,llama.cpp是一个用C/C++编写的开源项目,它的核心目标只有一个:用最高效的方式,在消费级硬件(比如你的笔记本电脑CPU)上运行大型语言模型。它不像PyTorch那样是个庞大的深度学习框架,它更像一个“推理引擎”,专注于把训练好的模型,以最小的资源消耗跑起来。 我刚开始接触大模型部署时,也被各种复杂的依赖和巨大的资源需求劝退过。直到用了llama.cpp,我才发现,原来在我的MacBook Pro上,也能流畅地和Llama 2这样的模型对话。这背后的功臣,主要就是两点:纯C/C++实现带来的极致性能,以及模型量化技术带来的体积与速度革命。量化这个词听起来有点技术,你可以把它想象成给模型“压缩图片”

By Ne0inhk