Skip to content

Commit 7a16c6d

Browse files
authored
Merge pull request #471 from InfiniTensor/fix/get-rope
fix: add basic get rope API and support mrope
2 parents 310c7fc + 40cefc6 commit 7a16c6d

2 files changed

Lines changed: 103 additions & 31 deletions

File tree

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,115 @@
11
#include "rotary_embedding.hpp"
22
#include "../../config/model_config.hpp"
33
#include "rotary_embedding_factory.hpp"
4+
#include <iomanip>
45
#include <memory>
6+
#include <sstream>
57
#include <string>
8+
#include <typeinfo>
9+
#include <unordered_map>
610

711
namespace infinilm::layers::rotary_embedding {
812

13+
namespace {
914
// Cache dictionary to avoid redundant allocations of RoPE instances.
1015
// thread_local ensures it is only visible within this compilation unit.
1116
thread_local std::unordered_map<std::string, std::shared_ptr<infinicore::nn::RoPE>> _ROPE_DICT;
1217

13-
std::shared_ptr<infinicore::nn::RoPE>
14-
get_rope(const std::shared_ptr<infinilm::config::ModelConfig> &model_config,
15-
const infinicore::Device &device) {
18+
std::string make_cache_key(size_t head_dim,
19+
size_t rotary_dim,
20+
size_t max_position_embeddings,
21+
double rope_theta,
22+
infinicore::nn::RoPE::Algo algo,
23+
const infinicore::DataType &dtype,
24+
const infinicore::Device &device,
25+
const std::shared_ptr<infinicore::nn::RopeScalingConfig> &scaling,
26+
const std::optional<std::vector<int>> &mrope_section,
27+
bool mrope_interleaved) {
28+
std::ostringstream oss;
29+
oss << "scaling_" << (scaling ? typeid(*scaling).name() : "none")
30+
<< "_head_" << head_dim
31+
<< "_rotary_" << rotary_dim
32+
<< "_max_" << max_position_embeddings
33+
<< "_theta_" << std::setprecision(17) << rope_theta
34+
<< "_algo_" << static_cast<int>(algo)
35+
<< "_dtype_" << static_cast<int>(dtype)
36+
<< "_dev" << device.toString();
1637

17-
// 1. Compute the actual rotary dimension
18-
size_t rotary_dim = model_config->get_rotary_dim();
19-
size_t head_dim = model_config->get_head_dim();
20-
21-
// 2. Resolve scaling config via the internal factory
22-
auto scaling = make_scaling_config(model_config);
23-
24-
// 3. Cache key must include rotary_dim AND the actual scaling type
25-
// to avoid reusing the same RoPE instance across models with different settings
26-
// (Enhancement: dynamically determine scaling_type instead of hardcoding "default")
27-
std::string scaling_type_str = "default";
28-
if (scaling) {
29-
// Assuming we can get the type string from the JSON for cache key generation,
30-
// or ideally, ScalingConfig should have a virtual std::string type_name() const method.
31-
// Here we read it from JSON for the cache key purpose only, keeping it decoupled from InfiniCore.
32-
const auto &rope_scaling_json = model_config->get_config_json()["rope_scaling"];
33-
if (rope_scaling_json.contains("type")) {
34-
scaling_type_str = rope_scaling_json["type"].get<std::string>();
35-
} else if (rope_scaling_json.contains("rope_type")) {
36-
scaling_type_str = rope_scaling_json["rope_type"].get<std::string>();
38+
if (mrope_section.has_value()) {
39+
oss << "_mrope";
40+
for (const auto section : mrope_section.value()) {
41+
oss << '_' << section;
3742
}
43+
oss << "_mrope_interleaved_" << (mrope_interleaved ? 1 : 0);
3844
}
45+
return oss.str();
46+
}
47+
48+
} // namespace
3949

40-
std::string cache_key = scaling_type_str + "_rope_dim_" + std::to_string(rotary_dim)
41-
+ "_dev_" + device.toString();
50+
std::shared_ptr<infinicore::nn::RoPE>
51+
get_rope(size_t head_dim,
52+
size_t rotary_dim,
53+
size_t max_position_embeddings,
54+
double rope_theta,
55+
infinicore::nn::RoPE::Algo algo,
56+
const infinicore::DataType &dtype,
57+
const infinicore::Device &device,
58+
std::shared_ptr<infinicore::nn::RopeScalingConfig> scaling,
59+
std::optional<std::vector<int>> mrope_section,
60+
bool mrope_interleaved) {
61+
const auto cache_key = make_cache_key(head_dim,
62+
rotary_dim,
63+
max_position_embeddings,
64+
rope_theta,
65+
algo,
66+
dtype,
67+
device,
68+
scaling,
69+
mrope_section,
70+
mrope_interleaved);
4271
auto it = _ROPE_DICT.find(cache_key);
4372
if (it != _ROPE_DICT.end()) {
4473
return it->second;
4574
}
4675

76+
auto rope = std::make_shared<infinicore::nn::RoPE>(head_dim,
77+
rotary_dim,
78+
max_position_embeddings,
79+
rope_theta,
80+
algo,
81+
dtype,
82+
device,
83+
scaling,
84+
mrope_section,
85+
mrope_interleaved);
86+
_ROPE_DICT.emplace(cache_key, rope);
87+
return rope;
88+
}
89+
90+
std::shared_ptr<infinicore::nn::RoPE>
91+
get_rope(const std::shared_ptr<infinilm::config::ModelConfig> &model_config,
92+
const infinicore::Device &device) {
93+
94+
size_t rotary_dim = model_config->get_rotary_dim();
95+
size_t head_dim = model_config->get_head_dim();
96+
auto scaling = make_scaling_config(model_config);
97+
4798
const auto &dtype = model_config->get_dtype();
4899
size_t max_position_embeddings = model_config->get<size_t>("max_position_embeddings");
49100
double rope_theta = model_config->get<double>("rope_theta");
50-
51101
infinicore::nn::RoPE::Algo algo = model_config->get_rope_algo();
52-
auto rope = std::make_shared<infinicore::nn::RoPE>(head_dim, rotary_dim, max_position_embeddings, rope_theta,
53-
algo, dtype, device, scaling);
54102

55-
_ROPE_DICT.emplace(cache_key, rope);
56-
return rope;
103+
return get_rope(head_dim,
104+
rotary_dim,
105+
max_position_embeddings,
106+
rope_theta,
107+
algo,
108+
dtype,
109+
device,
110+
scaling,
111+
std::nullopt,
112+
false);
57113
}
58114

59115
} // namespace infinilm::layers::rotary_embedding

‎csrc/layers/rotary_embedding/rotary_embedding.hpp‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,35 @@
22

33
#include "infinicore/nn/rope.hpp"
44
#include <memory>
5+
#include <optional>
6+
#include <string>
7+
#include <vector>
58

69
namespace infinilm::config {
710
class ModelConfig; // Forward declaration
811
}
912

1013
namespace infinilm::layers::rotary_embedding {
1114

15+
std::shared_ptr<infinicore::nn::RoPE>
16+
get_rope(size_t head_dim,
17+
size_t rotary_dim,
18+
size_t max_position_embeddings,
19+
double rope_theta,
20+
infinicore::nn::RoPE::Algo algo,
21+
const infinicore::DataType &dtype,
22+
const infinicore::Device &device,
23+
std::shared_ptr<infinicore::nn::RopeScalingConfig> scaling = nullptr,
24+
std::optional<std::vector<int>> mrope_section = std::nullopt,
25+
bool mrope_interleaved = false);
26+
1227
/**
1328
* @brief Public API to assemble and construct a complete RoPE module.
1429
*
1530
* @param model_config Model configuration.
1631
* @param device Device to create the cache on.
17-
* @param algo RoPE algorithm type (default: Algo::GPT_NEOX).
32+
* @todo Not Supported Yet: reading mrope params from config
33+
*
1834
*/
1935
std::shared_ptr<infinicore::nn::RoPE>
2036
get_rope(const std::shared_ptr<infinilm::config::ModelConfig> &model_config,

0 commit comments

Comments
 (0)