Skip to content

Commit

Permalink
fix: use relative path for model information (#1399)
Browse files Browse the repository at this point in the history
* feat: relative path for data (part1)

* chore: unit tests

* fix: unit tests

* fix: more

* fix: windows

* fix: comments

* fix: use fs path

* chore: move logic to file manager utils (#1405)

---------

Co-authored-by: vansangpfiev <[email protected]>
Co-authored-by: nguyenhoangthuan99 <[email protected]>
  • Loading branch information
3 people authored Oct 3, 2024
1 parent 65b1d20 commit 8657549
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 56 deletions.
9 changes: 7 additions & 2 deletions engine/commands/chat_completion_cmd.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#include "chat_completion_cmd.h"
#include "httplib.h"

#include "config/yaml_config.h"
#include "cortex_upd_cmd.h"
#include "database/models.h"
#include "model_status_cmd.h"
#include "run_cmd.h"
#include "server_start_cmd.h"
#include "trantor/utils/Logger.h"
#include "utils/logging_utils.h"
#include "config/yaml_config.h"

namespace commands {
namespace {
Expand Down Expand Up @@ -41,6 +41,8 @@ struct ChunkParser {

void ChatCompletionCmd::Exec(const std::string& host, int port,
const std::string& model_handle, std::string msg) {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
cortex::db::Models modellist_handler;
config::YamlHandler yaml_handler;
try {
Expand All @@ -49,7 +51,10 @@ void ChatCompletionCmd::Exec(const std::string& host, int port,
CLI_LOG("Error: " + model_entry.error());
return;
}
yaml_handler.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml))
.string());
auto mc = yaml_handler.GetModelConfig();
Exec(host, port, model_handle, mc, std::move(msg));
} catch (const std::exception& e) {
Expand Down
7 changes: 6 additions & 1 deletion engine/commands/model_get_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
namespace commands {

void ModelGetCmd::Exec(const std::string& model_handle) {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
cortex::db::Models modellist_handler;
config::YamlHandler yaml_handler;
try {
Expand All @@ -19,7 +21,10 @@ void ModelGetCmd::Exec(const std::string& model_handle) {
CLI_LOG("Error: " + model_entry.error());
return;
}
yaml_handler.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml))
.string());
auto model_config = yaml_handler.GetModelConfig();

std::cout << model_config.ToString() << std::endl;
Expand Down
11 changes: 8 additions & 3 deletions engine/commands/model_import_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ ModelImportCmd::ModelImportCmd(std::string model_handle, std::string model_path)
model_path_(std::move(model_path)) {}

void ModelImportCmd::Exec() {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
config::GGUFHandler gguf_handler;
config::YamlHandler yaml_handler;
cortex::db::Models modellist_utils_obj;
Expand All @@ -22,10 +24,13 @@ void ModelImportCmd::Exec() {
std::filesystem::path("imported") /
std::filesystem::path(model_handle_ + ".yml"))
.string();
cortex::db::ModelEntry model_entry{
model_handle_, "local", "imported",
model_yaml_path, model_handle_};
try {
// Use relative path for model_yaml_path. In case of import, we use absolute path for model
auto yaml_rel_path =
fmu::ToRelativeCortexDataPath(fs::path(model_yaml_path));
cortex::db::ModelEntry model_entry{model_handle_, "local", "imported",
yaml_rel_path.string(), model_handle_};

std::filesystem::create_directories(
std::filesystem::path(model_yaml_path).parent_path());
gguf_handler.Parse(model_path_);
Expand Down
7 changes: 6 additions & 1 deletion engine/commands/model_list_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
namespace commands {

void ModelListCmd::Exec() {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
auto models_path = file_manager_utils::GetModelsContainerPath();
cortex::db::Models modellist_handler;
config::YamlHandler yaml_handler;
Expand All @@ -29,7 +31,10 @@ void ModelListCmd::Exec() {
// auto model_entry = modellist_handler.GetModelInfo(model_handle);
try {
count += 1;
yaml_handler.ModelConfigFromFile(model_entry.path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.path_to_model_yaml))
.string());
auto model_config = yaml_handler.GetModelConfig();
table.add_row({std::to_string(count), model_entry.model,
model_entry.model_alias, model_config.engine,
Expand Down
10 changes: 7 additions & 3 deletions engine/commands/model_upd_cmd.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "model_upd_cmd.h"

#include "utils/file_manager_utils.h"
#include "utils/logging_utils.h"

namespace commands {
Expand All @@ -9,13 +9,17 @@ ModelUpdCmd::ModelUpdCmd(std::string model_handle)

void ModelUpdCmd::Exec(
const std::unordered_map<std::string, std::string>& options) {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
try {
auto model_entry = model_list_utils_.GetModelInfo(model_handle_);
if (model_entry.has_error()) {
CLI_LOG("Error: " + model_entry.error());
return;
}
yaml_handler_.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
auto yaml_fp = fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml));
yaml_handler_.ModelConfigFromFile(yaml_fp.string());
model_config_ = yaml_handler_.GetModelConfig();

for (const auto& [key, value] : options) {
Expand All @@ -25,7 +29,7 @@ void ModelUpdCmd::Exec(
}

yaml_handler_.UpdateModelConfig(model_config_);
yaml_handler_.WriteYamlFile(model_entry.value().path_to_model_yaml);
yaml_handler_.WriteYamlFile(yaml_fp.string());
CLI_LOG("Successfully updated model ID '" + model_handle_ + "'!");
} catch (const std::exception& e) {
CLI_LOG("Failed to update model with model ID '" + model_handle_ +
Expand Down
7 changes: 6 additions & 1 deletion engine/commands/run_cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ void RunCmd::Exec(bool chat_flag) {
}

try {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
auto model_entry = modellist_handler.GetModelInfo(*model_id);
if (model_entry.has_error()) {
CLI_LOG("Error: " + model_entry.error());
return;
}
yaml_handler.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml))
.string());
auto mc = yaml_handler.GetModelConfig();

// Check if engine existed. If not, download it
Expand Down
13 changes: 7 additions & 6 deletions engine/config/yaml_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

#include "utils/format_utils.h"
#include "utils/file_manager_utils.h"
#include "yaml_config.h"
namespace config {
// Method to read YAML file
Expand All @@ -14,6 +14,8 @@ void YamlHandler::Reset() {
yaml_node_.reset();
};
void YamlHandler::ReadYamlFile(const std::string& file_path) {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
try {
yaml_node_ = YAML::LoadFile(file_path);
// incase of model.yml file, we don't have files yet, create them
Expand All @@ -24,8 +26,9 @@ void YamlHandler::ReadYamlFile(const std::string& file_path) {
std::vector<std::string> v;
if (yaml_node_["engine"] &&
yaml_node_["engine"].as<std::string>() == "cortex.llamacpp") {
// TODO: change prefix to models:// with source from cortexso
v.emplace_back(s.substr(0, s.find_last_of('/')) + "/model.gguf");
auto abs_path = s.substr(0, s.find_last_of('/')) + "/model.gguf";
auto rel_path = fmu::ToRelativeCortexDataPath(fs::path(abs_path));
v.emplace_back(rel_path.string());
} else {
v.emplace_back(s.substr(0, s.find_last_of('/')));
}
Expand Down Expand Up @@ -286,9 +289,7 @@ void YamlHandler::WriteYamlFile(const std::string& file_path) const {
outFile << "version: " << yaml_node_["version"].as<std::string>() << "\n";
}
if (yaml_node_["files"] && yaml_node_["files"].size()) {
outFile << "files: # can be universal protocol (models://) "
"OR absolute local file path (file://) OR https remote URL "
"(https://)\n";
outFile << "files: # Can be relative OR absolute local file path\n";
for (const auto& source : yaml_node_["files"]) {
outFile << " - " << source << "\n";
}
Expand Down
53 changes: 36 additions & 17 deletions engine/controllers/models.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ void Models::PullModel(const HttpRequestPtr& req,
void Models::ListModel(
const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback) const {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
Json::Value ret;
ret["object"] = "list";
Json::Value data(Json::arrayValue);
Expand All @@ -73,8 +75,10 @@ void Models::ListModel(
for (const auto& model_entry : list_entry.value()) {
// auto model_entry = modellist_handler.GetModelInfo(model_handle);
try {

yaml_handler.ModelConfigFromFile(model_entry.path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.path_to_model_yaml))
.string());
auto model_config = yaml_handler.GetModelConfig();
Json::Value obj = model_config.ToJson();

Expand Down Expand Up @@ -106,6 +110,8 @@ void Models::ListModel(
void Models::GetModel(const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback,
const std::string& model_id) const {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
LOG_DEBUG << "GetModel, Model handle: " << model_id;
Json::Value ret;
ret["object"] = "list";
Expand All @@ -125,7 +131,10 @@ void Models::GetModel(const HttpRequestPtr& req,
callback(resp);
return;
}
yaml_handler.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
yaml_handler.ModelConfigFromFile(
fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml))
.string());
auto model_config = yaml_handler.GetModelConfig();

Json::Value obj = model_config.ToJson();
Expand All @@ -137,8 +146,8 @@ void Models::GetModel(const HttpRequestPtr& req,
resp->setStatusCode(k200OK);
callback(resp);
} catch (const std::exception& e) {
std::string message = "Fail to get model information with ID '" +
model_id + "': " + e.what();
std::string message =
"Fail to get model information with ID '" + model_id + "': " + e.what();
LOG_ERROR << message;
ret["data"] = data;
ret["result"] = "Fail to get model information";
Expand Down Expand Up @@ -171,16 +180,20 @@ void Models::DeleteModel(const HttpRequestPtr& req,
void Models::UpdateModel(const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback,
const std::string& model_id) const {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
auto json_body = *(req->getJsonObject());
try {
cortex::db::Models model_list_utils;
auto model_entry = model_list_utils.GetModelInfo(model_id);
config::YamlHandler yaml_handler;
yaml_handler.ModelConfigFromFile(model_entry.value().path_to_model_yaml);
auto yaml_fp = fmu::ToAbsoluteCortexDataPath(
fs::path(model_entry.value().path_to_model_yaml));
yaml_handler.ModelConfigFromFile(yaml_fp.string());
config::ModelConfig model_config = yaml_handler.GetModelConfig();
model_config.FromJson(json_body);
yaml_handler.UpdateModelConfig(model_config);
yaml_handler.WriteYamlFile(model_entry.value().path_to_model_yaml);
yaml_handler.WriteYamlFile(yaml_fp.string());
std::string message = "Successfully update model ID '" + model_id +
"': " + json_body.toStyledString();
LOG_INFO << message;
Expand Down Expand Up @@ -210,6 +223,8 @@ void Models::UpdateModel(const HttpRequestPtr& req,
void Models::ImportModel(
const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback) const {
namespace fs = std::filesystem;
namespace fmu = file_manager_utils;
if (!http_util::HasFieldInReq(req, callback, "model") ||
!http_util::HasFieldInReq(req, callback, "modelPath")) {
return;
Expand All @@ -219,14 +234,18 @@ void Models::ImportModel(
config::GGUFHandler gguf_handler;
config::YamlHandler yaml_handler;
cortex::db::Models modellist_utils_obj;

std::string model_yaml_path = (file_manager_utils::GetModelsContainerPath() /
std::filesystem::path("imported") /
std::filesystem::path(modelHandle + ".yml"))
.string();
cortex::db::ModelEntry model_entry{modelHandle, "local", "imported",
model_yaml_path, modelHandle};

try {
// Use relative path for model_yaml_path. In case of import, we use absolute path for model
auto yaml_rel_path =
fmu::ToRelativeCortexDataPath(fs::path(model_yaml_path));
cortex::db::ModelEntry model_entry{modelHandle, "local", "imported",
yaml_rel_path.string(), modelHandle};

std::filesystem::create_directories(
std::filesystem::path(model_yaml_path).parent_path());
gguf_handler.Parse(modelPath);
Expand Down Expand Up @@ -295,13 +314,13 @@ void Models::SetModelAlias(
if (result.has_error()) {
std::string message = result.error();
LOG_ERROR << message;
Json::Value ret;
ret["result"] = "Set alias failed!";
ret["modelHandle"] = model_handle;
ret["message"] = message;
auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret);
resp->setStatusCode(k400BadRequest);
callback(resp);
Json::Value ret;
ret["result"] = "Set alias failed!";
ret["modelHandle"] = model_handle;
ret["message"] = message;
auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret);
resp->setStatusCode(k400BadRequest);
callback(resp);
} else {
if (result.value()) {
std::string message = "Successfully set model alias '" + model_alias +
Expand Down
4 changes: 2 additions & 2 deletions engine/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ void RunServer() {
std::filesystem::path(config.logFolderPath) /
std::filesystem::path(cortex_utils::logs_folder));
trantor::FileLogger asyncFileLogger;
asyncFileLogger.setFileName(config.logFolderPath + "/" +
cortex_utils::logs_base_name);
asyncFileLogger.setFileName((std::filesystem::path(config.logFolderPath) /
std::filesystem::path(cortex_utils::logs_base_name)).string());
asyncFileLogger.setMaxLines(config.maxLogLines); // Keep last 100000 lines
asyncFileLogger.startLogging();
trantor::Logger::setOutputFunction(
Expand Down
1 change: 1 addition & 0 deletions engine/services/download_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ cpp::result<bool, std::string> DownloadService::Download(
CTL_INF("Existing file size: " << download_item.downloadUrl << " - "
<< download_item.localPath.string()
<< " - " << existing_file_size);
CTL_INF("Download item size: " << download_item.bytes.value());
auto missing_bytes = download_item.bytes.value() - existing_file_size;
if (missing_bytes > 0) {
CLI_LOG("Found unfinished download! Additional "
Expand Down
Loading

0 comments on commit 8657549

Please sign in to comment.