text-generation-inference/backends/trtllm/lib/backend.cpp

138 lines
5.0 KiB
C++
Raw Normal View History

2024-07-11 21:24:32 +00:00
#include <fstream>
#include <nvml.h>
2024-07-16 20:11:59 +00:00
#include <fmt/ranges.h>
2024-07-08 22:08:49 +00:00
#include <spdlog/spdlog.h>
#include "backend.h"
2024-07-08 22:08:49 +00:00
void huggingface::tgi::backends::InitializeBackend() {
SPDLOG_INFO("Initializing Backend...");
nvmlInit_v2();
2024-07-08 22:08:49 +00:00
initTrtLlmPlugins();
}
[[nodiscard]]
2024-07-08 22:08:49 +00:00
tle::ExecutorConfig huggingface::tgi::backends::GetExecutorConfig(const json &config, const std::string &workerPath) {
tle::ExecutorConfig execConfig(1);
// Get the compute capabilities of the current hardware
nvmlDevice_t device;
int32_t cudaComputeMajor = 0, cudaComputeMinor = 0;
2024-07-11 21:24:32 +00:00
if (nvmlDeviceGetHandleByIndex_v2(0, &device) == NVML_SUCCESS) {
SPDLOG_DEBUG("Successfully acquired nvmlDevice_t = 0");
if (nvmlDeviceGetCudaComputeCapability(device, &cudaComputeMajor, &cudaComputeMinor) == NVML_SUCCESS) {
SPDLOG_DEBUG(FMT_STRING("Detected sm_{:d}{:d} compute capabilities"), cudaComputeMajor, cudaComputeMinor);
}
}
2024-07-08 22:08:49 +00:00
// Single engine (TP = PP = 1) -> using leader mode (no MPI involved)
2024-07-11 21:24:32 +00:00
if (config["/pretrained_config/mapping/world_size"_json_pointer].get<uint8_t>() == 1) {
2024-07-08 22:08:49 +00:00
SPDLOG_INFO("Detected single engine deployment, using leader mode");
execConfig.setParallelConfig(tle::ParallelConfig(
tle::CommunicationType::kMPI,
tle::CommunicationMode::kLEADER,
std::nullopt,
std::nullopt,
std::nullopt
));
} else { // Multiple engines -> using orchestrator mode (MPI involved)
2024-07-08 22:08:49 +00:00
SPDLOG_INFO("Detected sharded engine deployment, using orchestrator mode");
execConfig.setParallelConfig(tle::ParallelConfig(
tle::CommunicationType::kMPI,
tle::CommunicationMode::kORCHESTRATOR,
std::nullopt,
std::nullopt,
tle::OrchestratorConfig(true, workerPath)
));
}
// Define some configuration variables
execConfig.setKvCacheConfig(tle::KvCacheConfig(true));
execConfig.setEnableChunkedContext(cudaComputeMajor >= 8);
return execConfig;
}
tle::SamplingConfig huggingface::tgi::backends::GetSamplingConfig(
uint32_t topK,
float_t topP,
float_t temperature,
uint64_t seed,
std::optional<int32_t> beamWidth = std::nullopt) {
return tle::SamplingConfig(
beamWidth.value_or(1),
topK,
topP,
std::nullopt,
std::nullopt,
std::nullopt,
seed,
std::nullopt,
temperature,
std::nullopt
);
}
huggingface::tgi::backends::TensorRtLlmBackend::TensorRtLlmBackend(
2024-07-08 22:08:49 +00:00
const std::filesystem::path &enginesFolder,
const std::filesystem::path &executorWorker
2024-07-11 21:24:32 +00:00
) :
config(json::parse(std::ifstream(enginesFolder / "config.json"))),
executor(
enginesFolder,
tensorrt_llm::executor::ModelType::kDECODER_ONLY,
GetExecutorConfig(config, executorWorker.string()
)) {
SPDLOG_INFO(FMT_STRING("Engine (version={})"), config["/version"_json_pointer].get_ref<const std::string &>());
}
bool huggingface::tgi::backends::TensorRtLlmBackend::IsReady() const {
return executor.canEnqueueRequests();
}
2024-07-03 08:27:53 +00:00
2024-07-16 20:11:59 +00:00
size_t huggingface::tgi::backends::TensorRtLlmBackend::NumResponsesReady() const {
return executor.getNumResponsesReady();
}
[[nodiscard("Returned request id needs to be provided back to gather generated tokens")]]
2024-07-03 08:27:53 +00:00
tle::IdType huggingface::tgi::backends::TensorRtLlmBackend::Submit(
2024-07-08 22:08:49 +00:00
const std::vector<tle::TokenIdType> &tokens,
const int32_t topK,
2024-07-03 08:27:53 +00:00
const float_t topP,
const float_t temperature,
2024-07-11 21:24:32 +00:00
const uint64_t seed
2024-07-03 08:27:53 +00:00
) {
#ifdef NDEBUG
SPDLOG_DEBUG(
FMT_STRING("Submitting inference over {:d} tokens to the executor ({:d} already in-flight)"),
2024-07-08 22:08:49 +00:00
tokens.size(),
executor.getLatestIterationStats().back().numActiveRequests
);
2024-07-16 20:11:59 +00:00
#else
SPDLOG_DEBUG(
2024-07-16 20:11:59 +00:00
FMT_STRING("Submitting inference [{}] to the executor ({:d} already in-flight)"),
fmt::join(tokens, ", "),
executor.getLatestIterationStats().front().numActiveRequests
2024-07-16 20:11:59 +00:00
);
#endif
2024-07-08 22:08:49 +00:00
const auto maxNumTokens = config["max_num_tokens"_json_pointer].get<size_t>();
const auto maxNewTokens = static_cast<int32_t>(std::max(1ul, maxNumTokens - tokens.size()));
const auto sampling = GetSamplingConfig(topK, topP, temperature, seed);
const auto output = tle::OutputConfig(false, false, false, true, false);
2024-07-16 20:11:59 +00:00
return executor.enqueueRequest(
tle::Request{tokens, maxNewTokens, true, sampling, output});
2024-07-11 21:24:32 +00:00
}
2024-07-16 20:11:59 +00:00
[[nodiscard("Generated tokens result must be used")]]
2024-07-11 21:24:32 +00:00
std::vector<tle::Response> huggingface::tgi::backends::TensorRtLlmBackend::Poll(const tle::IdType requestId) {
SPDLOG_DEBUG(FMT_STRING("Polling status for request {:d}"), requestId);
2024-07-11 21:24:32 +00:00
return executor.awaitResponses(requestId);
}
2024-07-15 07:36:01 +00:00
void huggingface::tgi::backends::TensorRtLlmBackend::Shutdown() {
SPDLOG_INFO("Shutting down executor");
executor.shutdown();
}