Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions tests/core/framework/config/config_json_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.

#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <string>
#include <string_view>

Expand Down Expand Up @@ -58,12 +59,63 @@ class ConfigJsonFileFlagGuard final {
std::string old_config_json_file_;
};

class DumpConfigJsonFlagGuard final {
public:
explicit DumpConfigJsonFlagGuard(const std::string& dump_config_json_file)
: old_enable_dump_config_json_(FLAGS_enable_dump_config_json),
old_dump_config_json_file_(FLAGS_dump_config_json_file) {
FLAGS_dump_config_json_file = dump_config_json_file;
}

~DumpConfigJsonFlagGuard() {
FLAGS_enable_dump_config_json = old_enable_dump_config_json_;
FLAGS_dump_config_json_file = old_dump_config_json_file_;
}

private:
bool old_enable_dump_config_json_;
std::string old_dump_config_json_file_;
};

class StartupConfigGuard final {
public:
StartupConfigGuard()
: kv_cache_config_(KVCacheConfig::get_instance()),
scheduler_config_(SchedulerConfig::get_instance()),
old_block_size_(kv_cache_config_.block_size()),
old_enable_prefix_cache_(kv_cache_config_.enable_prefix_cache()),
old_max_tokens_per_batch_(scheduler_config_.max_tokens_per_batch()),
old_enable_chunked_prefill_(
scheduler_config_.enable_chunked_prefill()) {}

~StartupConfigGuard() {
kv_cache_config_.block_size(old_block_size_)
.enable_prefix_cache(old_enable_prefix_cache_);
scheduler_config_.max_tokens_per_batch(old_max_tokens_per_batch_)
.enable_chunked_prefill(old_enable_chunked_prefill_);
}

private:
KVCacheConfig& kv_cache_config_;
SchedulerConfig& scheduler_config_;
int32_t old_block_size_;
bool old_enable_prefix_cache_;
int32_t old_max_tokens_per_batch_;
bool old_enable_chunked_prefill_;
};

void write_config_file(const std::filesystem::path& config_path,
std::string_view config_json) {
std::ofstream config_file(config_path);
config_file << config_json;
}

nlohmann::ordered_json read_json_file(const std::filesystem::path& file_path) {
std::ifstream input_file(file_path);
EXPECT_TRUE(input_file.is_open()) << file_path;
return nlohmann::ordered_json::parse(input_file);
}

std::filesystem::path config_test_file_path() {
const std::filesystem::path source_config_path =
std::filesystem::path(__FILE__).parent_path() / "config_test.json";
Expand Down Expand Up @@ -222,5 +274,49 @@ TEST(ConfigJsonTest, MissingJsonFileKeepsFlagDefaults) {
EXPECT_EQ(scheduler_config.max_seqs_per_batch(), 1024);
}

TEST(ConfigJsonTest, DumpStartupConfigSkipsWhenDisabled) {
const std::filesystem::path dump_path =
std::filesystem::temp_directory_path() /
"xllm_dump_config_json_test_disabled.json";
std::filesystem::remove(dump_path);
DumpConfigJsonFlagGuard flag_guard(dump_path.string());
FLAGS_enable_dump_config_json = false;

config::dump_startup_config();

EXPECT_FALSE(std::filesystem::exists(dump_path));
}

TEST(ConfigJsonTest, DumpStartupConfigWritesNonDefaultValuesOnly) {
const std::filesystem::path dump_path =
std::filesystem::temp_directory_path() /
"xllm_dump_config_json_test_non_default.json";
std::filesystem::remove(dump_path);
DumpConfigJsonFlagGuard flag_guard(dump_path.string());
StartupConfigGuard startup_config_guard;

KVCacheConfig::get_instance().block_size(256).enable_prefix_cache(false);
SchedulerConfig::get_instance()
.max_tokens_per_batch(2048)
.enable_chunked_prefill(false);
FLAGS_enable_dump_config_json = true;

config::dump_startup_config();

ASSERT_TRUE(std::filesystem::exists(dump_path));
const nlohmann::ordered_json config_json = read_json_file(dump_path);
EXPECT_EQ(config_json.at("block_size").get<int32_t>(), 256);
EXPECT_FALSE(config_json.at("enable_prefix_cache").get<bool>());
EXPECT_EQ(config_json.at("max_tokens_per_batch").get<int32_t>(), 2048);
EXPECT_FALSE(config_json.at("enable_chunked_prefill").get<bool>());

EXPECT_FALSE(config_json.contains("max_cache_size"));
EXPECT_FALSE(config_json.contains("kv_cache_dtype"));
EXPECT_FALSE(config_json.contains("max_seqs_per_batch"));
EXPECT_FALSE(config_json.contains("priority_strategy"));

std::filesystem::remove(dump_path);
}

} // namespace
} // namespace xllm
4 changes: 4 additions & 0 deletions xllm/core/common/global_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ limitations under the License.

DECLARE_string(config_json_file);

DECLARE_bool(enable_dump_config_json);

DECLARE_string(dump_config_json_file);

DECLARE_string(host);

DECLARE_int32(port);
Expand Down
1 change: 1 addition & 0 deletions xllm/core/framework/config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ cc_library(
DEPS
gflags::gflags
glog::glog
nlohmann_json::nlohmann_json
:util
)
13 changes: 13 additions & 0 deletions xllm/core/framework/config/beam_search_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ void BeamSearchConfig::from_json(const JsonReader& json) {
json.value_or<bool>("enable_topk_sorted", enable_topk_sorted()));
}

void BeamSearchConfig::append_config_json(
nlohmann::ordered_json& config_json) const {
const BeamSearchConfig default_config;
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, enable_beam_search_kernel);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, beam_width);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, enable_block_copy_kernel);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, enable_topk_sorted);
}

BeamSearchConfig& BeamSearchConfig::get_instance() {
static BeamSearchConfig config;
return config;
Expand Down
6 changes: 6 additions & 0 deletions xllm/core/framework/config/beam_search_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.
#pragma once

#include <cstdint>
#include <nlohmann/json_fwd.hpp>

#include "core/common/macros.h"
#include "core/framework/config/option_category.h"
Expand All @@ -33,6 +34,7 @@ class BeamSearchConfig final {

void from_flags();
void from_json(const JsonReader& json);
void append_config_json(nlohmann::ordered_json& config_json) const;
void initialize();

[[nodiscard]] static const OptionCategory& option_category() {
Expand All @@ -48,7 +50,11 @@ class BeamSearchConfig final {

PROPERTY(int32_t, beam_width) = 1;

#if defined(USE_NPU) || defined(USE_CUDA)
PROPERTY(bool, enable_block_copy_kernel) = true;
#else
PROPERTY(bool, enable_block_copy_kernel) = false;
#endif

PROPERTY(bool, enable_topk_sorted) = true;
};
Expand Down
88 changes: 88 additions & 0 deletions xllm/core/framework/config/config_json_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,46 @@ limitations under the License.
#include <glog/logging.h>

#include <exception>
#include <filesystem>
#include <fstream>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <system_error>

#include "core/framework/config/beam_search_config.h"
#include "core/framework/config/disagg_pd_config.h"
#include "core/framework/config/distributed_config.h"
#include "core/framework/config/dit_config.h"
#include "core/framework/config/eplb_config.h"
#include "core/framework/config/execution_config.h"
#include "core/framework/config/kernel_config.h"
#include "core/framework/config/kv_cache_config.h"
#include "core/framework/config/kv_cache_store_config.h"
#include "core/framework/config/load_config.h"
#include "core/framework/config/model_config.h"
#include "core/framework/config/parallel_config.h"
#include "core/framework/config/profile_config.h"
#include "core/framework/config/rec_config.h"
#include "core/framework/config/scheduler_config.h"
#include "core/framework/config/service_config.h"
#include "core/framework/config/speculative_config.h"

DEFINE_string(config_json_file,
"",
"Path to a JSON config file. Values in the file override "
"command-line flag values.");

DEFINE_bool(enable_dump_config_json,
false,
"Whether to dump the resolved startup config as JSON.");

DEFINE_string(dump_config_json_file,
"xllm_config.json",
"Path to write the resolved startup config as JSON. Used only "
"when enable_dump_config_json is true.");

namespace xllm::config {
namespace {

Expand Down Expand Up @@ -84,6 +114,30 @@ void reset_parsed_json_config_if_path_changed() {
parsed_json_config_once() = std::make_unique<std::once_flag>();
}

nlohmann::ordered_json build_startup_config_json() {
nlohmann::ordered_json config_json = nlohmann::ordered_json::object();

ServiceConfig::get_instance().append_config_json(config_json);
ModelConfig::get_instance().append_config_json(config_json);
LoadConfig::get_instance().append_config_json(config_json);
KVCacheConfig::get_instance().append_config_json(config_json);
KVCacheStoreConfig::get_instance().append_config_json(config_json);
BeamSearchConfig::get_instance().append_config_json(config_json);
SchedulerConfig::get_instance().append_config_json(config_json);
ParallelConfig::get_instance().append_config_json(config_json);
EPLBConfig::get_instance().append_config_json(config_json);
DistributedConfig::get_instance().append_config_json(config_json);
DisaggPDConfig::get_instance().append_config_json(config_json);
SpeculativeConfig::get_instance().append_config_json(config_json);
ProfileConfig::get_instance().append_config_json(config_json);
ExecutionConfig::get_instance().append_config_json(config_json);
KernelConfig::get_instance().append_config_json(config_json);
DiTConfig::get_instance().append_config_json(config_json);
RecConfig::get_instance().append_config_json(config_json);

return config_json;
}

} // namespace

JsonReader load_json_file(const std::string& config_path) {
Expand All @@ -109,4 +163,38 @@ const std::optional<JsonReader>& get_parsed_json_config() {
return parsed_json_config();
}

void dump_startup_config() {
if (!FLAGS_enable_dump_config_json) {
return;
}

const std::filesystem::path dump_path =
std::filesystem::path(FLAGS_dump_config_json_file).lexically_normal();
if (dump_path.has_parent_path()) {
std::error_code error_code;
std::filesystem::create_directories(dump_path.parent_path(), error_code);
if (error_code) {
LOG(FATAL) << "Failed to create startup config dump directory: "
<< dump_path.parent_path().string()
<< ", error: " << error_code.message();
}
}

std::ofstream output_stream(dump_path);
if (!output_stream.is_open()) {
LOG(FATAL) << "Failed to open startup config dump file: "
<< dump_path.string();
}

const nlohmann::ordered_json config_json = build_startup_config_json();
output_stream << config_json.dump(2) << "\n";
output_stream.close();
if (!output_stream.good()) {
LOG(FATAL) << "Failed to write startup config dump file: "
<< dump_path.string();
}

LOG(INFO) << "Dumped startup config to " << dump_path.string();
}

} // namespace xllm::config
17 changes: 17 additions & 0 deletions xllm/core/framework/config/config_json_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.

#pragma once

#include <nlohmann/json.hpp>
#include <optional>
#include <string>
#include <string_view>
Expand All @@ -29,4 +30,20 @@ JsonReader parse_json_string(std::string_view config_json);

const std::optional<JsonReader>& get_parsed_json_config();

void dump_startup_config();

} // namespace xllm::config

#define APPEND_JSON_VALUE_IF_NOT_DEFAULT( \
config_json, key, value, default_value) \
do { \
const auto& config_json_value = (value); \
if (config_json_value != (default_value)) { \
(config_json)[key] = config_json_value; \
} \
} while (false)

#define APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT( \
config_json, default_config, property) \
APPEND_JSON_VALUE_IF_NOT_DEFAULT( \
config_json, #property, property(), (default_config).property())
19 changes: 19 additions & 0 deletions xllm/core/framework/config/disagg_pd_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,25 @@ void DisaggPDConfig::from_json(const JsonReader& json) {
transfer_listen_port()));
}

void DisaggPDConfig::append_config_json(
nlohmann::ordered_json& config_json) const {
const DisaggPDConfig default_config;
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, enable_disagg_pd);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, enable_pd_ooc);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, disagg_pd_port);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, instance_role);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, kv_cache_transfer_type);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, kv_cache_transfer_mode);
APPEND_CONFIG_JSON_VALUE_IF_NOT_DEFAULT(
config_json, default_config, transfer_listen_port);
}

DisaggPDConfig& DisaggPDConfig::get_instance() {
static DisaggPDConfig config;
return config;
Expand Down
2 changes: 2 additions & 0 deletions xllm/core/framework/config/disagg_pd_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.
#pragma once

#include <cstdint>
#include <nlohmann/json_fwd.hpp>
#include <string>

#include "core/common/macros.h"
Expand All @@ -36,6 +37,7 @@ class DisaggPDConfig final {

void from_flags();
void from_json(const JsonReader& json);
void append_config_json(nlohmann::ordered_json& config_json) const;
void initialize();
void normalize_mlu(KVCacheConfig& kv_cache_config,
SchedulerConfig& scheduler_config);
Expand Down
Loading
Loading