Skip to content

Commit 76434b8

Browse files
authored
Add BF16 support to sampler (pytorch#22094)
Differential Revision: D117223300 Pull Request resolved: pytorch#22094
1 parent 0447246 commit 76434b8

3 files changed

Lines changed: 45 additions & 2 deletions

File tree

‎extension/llm/sampler/sampler.cpp‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
// This is a modified version of https://github.com/karpathy/llama2.c.git
1010
// @lint-ignore-every LICENSELINT
11+
// @lint-ignore-every CLANGTIDY facebook-hte-Deprecated
1112
/**
1213
* MIT License
1314
*
@@ -250,12 +251,21 @@ int32_t Sampler::sample(T* logits) {
250251
return next;
251252
}
252253

254+
template <>
255+
int32_t Sampler::sample<executorch::aten::BFloat16>(
256+
executorch::aten::BFloat16* logits) {
257+
float_logits_buffer_.resize(vocab_size_);
258+
for (int i = 0; i < vocab_size_; i++) {
259+
float_logits_buffer_[i] = static_cast<float>(logits[i]);
260+
}
261+
262+
return sample(float_logits_buffer_.data());
263+
}
264+
253265
template int32_t Sampler::sample<float>(float* logits);
254266
template int32_t Sampler::sample<uint16_t>(uint16_t* logits);
255267
template int32_t Sampler::sample<executorch::aten::Half>(
256268
executorch::aten::Half* logits);
257-
template int32_t Sampler::sample<executorch::aten::BFloat16>(
258-
executorch::aten::BFloat16* logits);
259269

260270
} // namespace llm
261271
} // namespace extension

‎extension/llm/sampler/sampler.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <cstdlib>
1515
#include <cstring>
1616
#include <memory>
17+
#include <vector>
1718
#ifdef USE_ATEN_LIB
1819
#include <torch/torch.h>
1920
#endif
@@ -80,8 +81,13 @@ class ET_EXPERIMENTAL Sampler {
8081
// 0 (or >= vocab_size_) means top-k is disabled.
8182
int32_t topk_ = 0;
8283
unsigned long long rng_state_;
84+
std::vector<float> float_logits_buffer_;
8385
};
8486

87+
template <>
88+
int32_t Sampler::sample<executorch::aten::BFloat16>(
89+
executorch::aten::BFloat16* logits);
90+
8591
} // namespace llm
8692
} // namespace extension
8793
} // namespace executorch

‎extension/llm/sampler/test/test_sampler.cpp‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9+
// @lint-ignore-every CLANGTIDY facebook-hte-Deprecated
10+
911
#include <executorch/extension/llm/sampler/sampler.h>
1012

1113
#include <set>
14+
#include <vector>
1215

1316
#include <gtest/gtest.h>
1417
#include <torch/torch.h>
@@ -42,6 +45,30 @@ TEST(SamplerTest, TestArgMaxWithFP16) {
4245
EXPECT_EQ(sampler.sample(input.data_ptr<c10::Half>()), 396);
4346
}
4447

48+
TEST(SamplerTest, TestBFloat16SamplingUsesFloatArithmetic) {
49+
constexpr int kVocabSize = 256;
50+
constexpr unsigned long long kSeed = 42;
51+
Sampler float_sampler{kVocabSize, 1.0f, 1.0f, kSeed};
52+
Sampler bf16_sampler{kVocabSize, 1.0f, 1.0f, kSeed};
53+
54+
std::vector<executorch::aten::BFloat16> bf16_logits;
55+
std::vector<float> float_logits;
56+
bf16_logits.reserve(kVocabSize);
57+
float_logits.reserve(kVocabSize);
58+
bool observed_bf16_rounding = false;
59+
for (int i = 0; i < kVocabSize; i++) {
60+
const float input_logit = static_cast<float>(i) * 0.001f - 0.128f;
61+
bf16_logits.emplace_back(input_logit);
62+
float_logits.push_back(static_cast<float>(bf16_logits.back()));
63+
observed_bf16_rounding |= float_logits.back() != input_logit;
64+
}
65+
66+
ASSERT_TRUE(observed_bf16_rounding);
67+
EXPECT_EQ(
68+
bf16_sampler.sample(bf16_logits.data()),
69+
float_sampler.sample(float_logits.data()));
70+
}
71+
4572
TEST(SamplerTest, TestTopKRestrictsToCandidates) {
4673
// With topk=3, sampling must always return one of the top-3 indices,
4774
// regardless of the random draw.

0 commit comments

Comments
 (0)