乐于分享
好东西不私藏

TensorRT-LLM 0.5.0 源码之三十五

TensorRT-LLM 0.5.0 源码之三十五

BaseSamplingLayer::forward

  1. 1. skip_all, return
  2. 2. skip_any, copy logits
  3. 3. invokeBatchApplyTemperaturePenalty
  4. 4. invokeBatchApplyRepetitionPenalty
  5. 5. invokeMinLengthPenalty
  6. 6. runSampling
template <typename T>void BaseSamplingLayer<T>::forward(DecodingOutputParams& outputs, ForwardParams const& params){    auto* logits = params.logits.template getPtr<T>();#define ALL_OF(p_, sz_, dt_, v_) (std::all_of(p_, p_ + sz_, [&](dt_ b) { return b == v_; }))    bool* skip_decode = skip_decode_ + ite * local_batch_size;    if (ALL_OF(skip_decode, local_batch_size, bool, true))    {        // No sample in the current batch to do TopX sampling.        return;    }    skip_any_ = std::any_of(skip_decode, skip_decode + local_batch_size, [](bool b) { return b; });    if (skip_any_)    {        // A TopX Sampling layer directly changes the logit values. In case of        // skip_any==true, meaning topk and topp layers will run simultaneously for        // a batch in the same step. We copy the logits to an internal buffer, not        // affecting the other sampling layers.        TLLM_CHECK(params.logits.size() == local_batch_size * vocab_size_padded_);        cudaD2Dcpy(runtime_logits_buf_, logits, params.logits.size());        logits = runtime_logits_buf_;    }    if (embedding_bias != nullptr        || !ALL_OF(std::begin(mTemperature) + ite * local_batch_size, local_batch_size, float, 1.0f))    {        invokeBatchApplyTemperaturePenalty(logits, embedding_bias, temperature_buf_ + ite * local_batch_size,            local_batch_size, vocab_size_, vocab_size_padded_, stream_);    }    if (step > 1 && repetition_penalty_type_ != RepetitionPenaltyType::None)    {        if (!ALL_OF(std::begin(mRepetitionPenalty) + ite * local_batch_size, local_batch_size, float, default_value))        {            invokeBatchApplyRepetitionPenalty(logits, repetition_penalty_buf_ + ite * local_batch_size,                outputs.output_ids_ptr.template getPtr<const int*>(), outputs.sequence_length->getPtr<const int>(),                batch_size, local_batch_size, vocab_size_padded_, input_lengths, repetition_penalty_type_,                params.max_seq_len, stream_);        }    }    invokeMinLengthPenalty(logits, min_lengths_buf_ + ite * local_batch_size, end_ids,        outputs.sequence_length->getPtr<const int>(), input_lengths, local_batch_size, vocab_size_padded_, stream_);    runSampling(outputs, params);    if (is_free_buffer_after_forward_)    {        freeBuffer();    }}

invokeApplyTemperaturePenalty

1.float, 超出 vocab_size 的部分 logits 为 -MXT_T_VAL2.half, 只处理 vocab_size 内的数。当 vocab_size %20, vocab_size_padd %2  0 时有效。3. temperature 有一个 1e-6f 的epsion值

// TODO Add half2 implementationtemplate <typename T>__global__ void applyTemperaturePenalty(T* logits, const T* bias, const float temperature_inverse, const int m,    const int vocab_size, const int vocab_size_padd){    const bool IS_FP16 = std::is_same<T, half>::value;    const T MAX_T_VAL = (IS_FP16) ? 65504.F : FLT_MAX;    for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < m * vocab_size_padd;         index += blockDim.x * gridDim.x)    {        T bias_val = bias == nullptr ? (T) (0.0f) : bias[index % vocab_size_padd];        if (index % vocab_size_padd < vocab_size)        {            logits[index] = (logits[index] + bias_val) * (T) temperature_inverse;        }        else        {            logits[index] = -MAX_T_VAL;        }    }}template <>__global__ void applyTemperaturePenalty(half2* logits, const half2* bias, const float temperature_inverse,    const int batch_size, const int vocab_size, const int vocab_size_padded){    assert(vocab_size % 2 == 0);    assert(vocab_size_padded % 2 == 0);    const half2 mask_val = __float2half2_rn(-65504.0f);    const half2 temp_inv = __float2half2_rn(temperature_inverse);    const int half_vocab_size = vocab_size / 2;    const int half_vocab_size_padded = vocab_size_padded / 2;    for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < batch_size * half_vocab_size_padded;         index += blockDim.x * gridDim.x)    {        int vocab_idx = index % half_vocab_size_padded;        half2 logit = vocab_idx < half_vocab_size ? __ldg(&logits[index]) : mask_val;        if (vocab_idx < half_vocab_size)        {            if (bias != nullptr)            {                logit = __hadd2(logit, bias[vocab_idx]);            }            logits[index] = __hmul2(logit, temp_inv);        }    }}template <typename T>void invokeApplyTemperaturePenalty(T* logits, const T* bias, const float temperature, const int batch_size,    const int vocab_size, const int vocab_size_padd, cudaStream_t stream){    dim3 grid(min(vocab_size_padd, 1024));    dim3 block(min(batch_size * vocab_size_padd / block.x, 65536));    const T temperature_inverse = (T) (1.f / (temperature + 1e-6f));    if (std::is_same<T, half>::value && vocab_size % 2 == 0 && vocab_size_padd % 2 == 0)    {        applyTemperaturePenalty<<<grid, block, 0, stream>>>(reinterpret_cast<half2*>(logits),            reinterpret_cast<const half2*>(bias), temperature_inverse, batch_size, vocab_size, vocab_size_padd);    }    else    {        applyTemperaturePenalty<T>            <<<grid, block, 0, stream>>>(logits, bias, temperature_inverse, batch_size, vocab_size, vocab_size_padd);    }}template void invokeApplyTemperaturePenalty(float* logits, const float* bias, const float temperature,    const int batch_size, const int vocab_size, const int vocab_size_padd, cudaStream_t stream);template void invokeApplyTemperaturePenalty(half* logits, const half* bias, const float temperature,    const int batch_size, const int vocab_size, const int vocab_size_padd, cudaStream_t stream);

batchApplyTemperaturePenalty

template <typename T>__global__ void batchApplyTemperaturePenalty(T* logits, const T* bias, const float* temperatures, const int batch_size,    const int vocab_size, const int vocab_size_padd){    // TODO: Add macro or device function to get MAX_T_VAL.    const bool IS_FP16 = std::is_same<T, half>::value;    const T MAX_T_VAL = (IS_FP16) ? 65504.F : FLT_MAX;    extern __shared__ float inv_temperatures[];    if (threadIdx.x < batch_size)    {        inv_temperatures[threadIdx.x] = 1.0f / (temperatures[threadIdx.x] + 1e-6f);    }    __syncthreads();    for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < batch_size * vocab_size_padd;         index += blockDim.x * gridDim.x)    {        int batch_idx = index / vocab_size_padd;        int vocab_idx = index % vocab_size_padd;        T logit = (vocab_idx < vocab_size) ? logits[index] : -MAX_T_VAL;        if (vocab_idx < vocab_size)        {            if (bias != nullptr)            {                logit += bias[vocab_idx];            }            logit *= inv_temperatures[batch_idx];        }        logits[index] = logit;    }}__global__ void batchApplyTemperaturePenalty_h2(half2* logits, const half2* bias, const float* temperatures,    const int batch_size, const int vocab_size, const int vocab_size_padded){    assert(vocab_size % 2 == 0);    assert(vocab_size_padded % 2 == 0);    extern __shared__ half2 h2_inv_temperatures[];    if (threadIdx.x < batch_size)    {        h2_inv_temperatures[threadIdx.x] = __float2half2_rn(1.f / (temperatures[threadIdx.x] + 1e-6f));    }    __syncthreads();    const half2 mask_val = __float2half2_rn(-65504.0f);    const int half_vocab_size = vocab_size / 2;    const int half_vocab_size_padded = vocab_size_padded / 2;    for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < batch_size * half_vocab_size_padded;         index += blockDim.x * gridDim.x)    {        int batch_idx = index / half_vocab_size_padded;        int vocab_idx = index % half_vocab_size_padded;        half2 logit = vocab_idx < half_vocab_size ? __ldg(&logits[index]) : mask_val;        if (vocab_idx < half_vocab_size)        {            if (bias != nullptr)            {                logit = __hadd2(logit, bias[vocab_idx]);            }            logits[index] = __hmul2(logit, h2_inv_temperatures[batch_idx]);        }    }}template <typename T>void invokeBatchApplyTemperaturePenalty(T* logits, const T* bias, const float* temperatures, const int batch_size,    const int vocab_size, const int vocab_size_padd, cudaStream_t stream){    TLLM_LOG_DEBUG("%s start", __PRETTY_FUNCTION__);    dim3 grid(min(vocab_size_padd, 1024));    dim3 block(min(batch_size * vocab_size_padd / block.x, 65536));    if (std::is_same<T, half>::value && vocab_size % 2 == 0 && vocab_size_padd % 2 == 0)    {        size_t smem_size = sizeof(half2) * batch_size;        batchApplyTemperaturePenalty_h2<<<grid, block, smem_size, stream>>>(reinterpret_cast<half2*>(logits),            reinterpret_cast<const half2*>(bias), temperatures, batch_size, vocab_size, vocab_size_padd);    }    else    {        size_t smem_size = sizeof(float) * batch_size;        batchApplyTemperaturePenalty<T>            <<<grid, block, smem_size, stream>>>(logits, bias, temperatures, batch_size, vocab_size, vocab_size_padd);    }}template void invokeBatchApplyTemperaturePenalty(float* logits, const float* bias, const float* temperatures,    const int batch_size, const int vocab_size, const int vocab_size_padd, cudaStream_t stream);template void invokeBatchApplyTemperaturePenalty(half* logits, const half* bias, const float* temperatures,    const int batch_size, const int vocab_size, const int vocab_size_padd, cudaStream_t stream);

batchApplyRepetitionPenalty

template <typename T>void invokeBatchApplyRepetitionPenalty(T* logits, const float* penalties, const int** output_ids,    const int* sequence_lengths, const int batch_size, const int local_batch_size, const int vocab_size,    const int* input_lengths, RepetitionPenaltyType penalty_type, int max_seq_len, cudaStream_t stream){    // Inputs    //   logits [local_batch_size, vocab_size] : logit values.    //   penalties [local_batch_size] : repetition penalty factors.    //   output_ids int**, [bs] array, each array has [1, max_seq_len]    //   sequence_lengths int*, [bs]    //   input_lengths [local_batch_size], input lengths    TLLM_LOG_DEBUG("%s start", __PRETTY_FUNCTION__);    dim3 grid(min(max_seq_len, 1024));    dim3 block(batch_size);    size_t smem_size = max_seq_len * (sizeof(float) + sizeof(int));    if (penalty_type == RepetitionPenaltyType::Additive)    {        batchApplyRepetitionPenalty<T, RepetitionPenaltyType::Additive><<<grid, block, smem_size, stream>>>(            logits, penalties, output_ids, sequence_lengths, batch_size, vocab_size, input_lengths, max_seq_len);    }    else if (penalty_type == RepetitionPenaltyType::Multiplicative)    {        batchApplyRepetitionPenalty<T, RepetitionPenaltyType::Multiplicative><<<grid, block, smem_size, stream>>>(            logits, penalties, output_ids, sequence_lengths, batch_size, vocab_size, input_lengths, max_seq_len);    }    else if (penalty_type == RepetitionPenaltyType::None)    {        // do nothing    }}template void invokeBatchApplyRepetitionPenalty(float* logits, const float* penalties, const int** output_ids,    const int* sequence_lengths, const int batch_size, const int local_batch_size, const int vocab_size,    const int* input_lengths, RepetitionPenaltyType penalty_type, int max_seq_len, cudaStream_t stream);template void invokeBatchApplyRepetitionPenalty(half* logits, const float* penalties, const int** output_ids,    const int* sequence_lengths, const int batch_size, const int local_batch_size, const int vocab_size,    const int* input_lengths, RepetitionPenaltyType penalty_type, int max_seq_len, cudaStream_t stream);
template <typename T, RepetitionPenaltyType penalty_type>__global__ void batchApplyRepetitionPenalty(T* logits, const float* penalties, const int** output_ids,    const int* sequence_lengths, const int batch_size, const int vocab_size, const int* input_lengths,    const int max_seq_len){    extern __shared__ float penalty_logits[]; // max_seq_len * (sizeof(float) + sizeof(int));    int* penalty_indices = (int*) (penalty_logits + max_seq_len); // [max_seq_len ,]    const int batch_idx = blockIdx.x; // dim for B    const float penalty = penalties[batch_idx];    const int current_step = sequence_lengths[batch_idx];    logits += batch_idx * vocab_size; // logits.shape = [B, V]    // Phase 1. Find indices to penalize and keep the penalized values.    // A vocab id can appear multiple times but should be penalized once.    // threadIdx.x for T(current_sequnce_length)    for (int index = threadIdx.x; index < current_step; index += blockDim.x)    {        // output_ids shape: (beam_size, input_len + output_len), [beamsize, max_seq_len]        // blockIdx.y is dim for BeamSize, 这里blockIdx.y=0, blockDim.y=1        int penalty_index = output_ids[batch_idx][blockIdx.y * max_seq_len + index];        assert(penalty_index < vocab_size);        penalty_indices[index] = penalty_index; // penalty_index in V        float logit = (float) logits[penalty_index];        if (penalty_type == RepetitionPenaltyType::Additive)        {            penalty_logits[index] = logit - penalty;        }        else if (penalty_type == RepetitionPenaltyType::Multiplicative)        {            penalty_logits[index] = logit < 0.0f ? logit * penalty : logit / penalty;        }        else if (penalty_type == RepetitionPenaltyType::None)        {            penalty_logits[index] = logit;        }        else        {            // Unsupported type            assert(false);        }    }    if (blockDim.x > 32) // not in wrap, wrap size is 32    {        __syncthreads();    }    // Phase 2. Replace a logit value by the penalized one.    for (int index = threadIdx.x; index < current_step; index += blockDim.x)    {        logits[penalty_indices[index]] = penalty_logits[index];    }}

batchApplyMinLengthPenalty

template <typename T>void invokeMinLengthPenalty(T* logits, const int* min_lengths, const int* end_ids, const int* sequnece_lengths,    const int* input_lengths, const int batch_size, const int vocab_size_padded, cudaStream_t stream){    const int block_size = min(batch_size, 1024); // B    const int grid_size = (batch_size + block_size - 1) / block_size;    batchApplyMinLengthPenalty<<<grid_size, block_size, 0, stream>>>(        logits, min_lengths, end_ids, sequnece_lengths, input_lengths, vocab_size_padded);}template void invokeMinLengthPenalty(float* logits, const int* min_lengths, const int* end_ids,    const int* sequnece_lengths, const int* input_lengths, const int batch_size, const int vocab_size_padded,    cudaStream_t stream);template void invokeMinLengthPenalty(half* logits, const int* min_lengths, const int* end_ids,    const int* sequnece_lengths, const int* input_lengths, const int batch_size, const int vocab_size_padded,    cudaStream_t stream);
template <typename T>__global__ void batchApplyMinLengthPenalty(T* logits, const int* min_lengths, const int* end_ids,    const int* sequence_lengths, const int* input_lengths, const int vocab_size_padded){    int bid = threadIdx.x + blockIdx.x * blockDim.x; // batch index    auto const input_length{input_lengths == nullptr ? 0 : input_lengths[bid]};    // We need +1 because sequence_lengths = num_gen_tokens + input_length - 1, which is equal to the length of k/v    // caches.    // sequence_lengths = num_gen_tokens + input_length - 1 这里的-1应该不包含最后的end_id    // 这里的+1,应该是指当前step的长度。    if (sequence_lengths[bid] + 1 - input_length < min_lengths[bid])    {           // 根据数据类型T选择一个极小的负数(-FLT_MAX或half类型的最小值-65504.0f)。在Softmax函数中,这个值会使得对应的概率接近于零。        T mask_val = (std::is_same<T, half>::value) ? -65504.0f : -FLT_MAX;        // 通过bid * vocab_size_padded + end_ids[bid]精确找到当前批次样本bid对应的end_id在logits数组中的位置,并将其替换为掩码值。        // 小于min_lengths[bid] 的时候,ends_ids[bid]位置的prob为0,不采样,鼓励多生成。        logits[bid * vocab_size_padded + end_ids[bid]] = mask_val;    }}

参考文献

  • • https://github.com/NVIDIA/TensorRT-LLM/blob/v0.5.0/cpp/tensorrt_llm/kernels/samplingPenaltyKernels.cu
点个「赞」+「在看」❤️
让我们知道这份文字有温暖到你,也是我们持续创作的最大动力!
推荐
技能:规定智能体应该如何思考
借助AI进行写作与思考
大型数据集与结构化数据库:经济学家使用Claude Code
从 EDGAR 文件到结构化数据库:使用 Claude Code
循环工程:设计编码代理系统,而不是每次都手动提示
VoxCPM2 技术报告
信息差的消失
Agent 数据生产与训练
基准测试设计:选择开放模型测试与封闭模型测试
gRPC 使用建议
flashinfer.sampling 实现四
AI 时代的组织变更
TensorRT-LLM 0.5.0 源码之二十七
flashinfer.sampling 实现三
什么是循环工程?AI 编码智能体的新范式
Trae IDE 实战指南:核心AI功能、Skill运用与项目开发全流程
Small matrix multiplication - Triton
从空文件夹到生成图表:Claude Code 实战教程
Claude Code 入门:研究者配置指南
Claude Code 究竟擅长什么?一次实测验证
GLM-5.2:面向长时序任务打造
Anthropic Fable 5
循环工程(Loop Engineering)
Agent SFT 标准数据格式 + Loss Mask 完整实现
4D Parallelism
TileLang与OpenAI Triton的核心区别
TensorRT-LLM 0.5.0 源码之二十六
Agent SFT 数据
Claude Code 的上限,就是你的上限
如何用Claude Code提升软件工程工作效率、改善生活
LLM推理优化的核心技术:深入理解KV缓存与分页注意力机制
MiMo-V2-Flash技术报告
AI原生开发中的MCP与CLI对比
Qwen3-TTS 技术报告
PagedAttention
如何让AI听懂你的“话外音”?GOAT-SLM模型实现更懂情感的语言交互
FlashAttention与PagedAttention详解:拯救GPU显存,让大模型飞起来的核心技术
LM-as-a-judge:LLM评估指南
LLM Sequence Packing
深入了解SmoothQuant:大模型高效量化背后的数学原理
语音合成(TTS)分句生成拼接时的响度一致性问题:现状、成因与对策
当扩散模型遇上流匹配:原来是一回事儿
语音合成中的“一对多”问题主流模型解决方案分析
使用LoRA对LLM进行微调的实用技巧
语音合成(TTS)中文自然度:问题、成因、解决方案
语音合成(TTS)跳跃与重复问题的解析:成因、机制及解决方案
最新!SpeechLLM 综述:架构、能力、挑战与未来全揭秘