Skip to content

Cmake builds libgit2 and --pull_hf_mode for ovms #3105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 62 commits into
base: main
Choose a base branch
from

Conversation

rasapala
Copy link
Collaborator

@rasapala rasapala commented Mar 4, 2025

🛠 Summary

JIRA CVS-163308
Current usage:
bazel-bin/src/ovms --pull_hf_model --source_model OpenVINO/TinyLlama-1.1B-Chat-v1.0-int8-ov --repo_path /download

🧪 Checklist

  • Unit tests added.
  • The documentation updated.
  • Change follows security best practices.
    ``

src/server.cpp Outdated
parser.prepare(&serverSettings, &modelsSettings);
parser.prepare(&serverSettings, &modelsSettings, &hfDownloader);

if (hfDownloader.pull_hf_model) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be responsibility of ServableModule?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should separate the server mode and hf download mode.

import fnmatch
import sys

def remove_japanese_txt(directory):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are using this in other repo's already. Calling this should be some kind of bazel procedure loaded from *.bzl file

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to placed exactly in the repository ctx directory on every build. This script will remove a directory not only files because we cannot filter the files by extension like it was done in the other python script.

@rasapala rasapala changed the title Cmake builds libgit2 [WIP] Cmake builds libgit2 Mar 19, 2025
@rasapala rasapala changed the title [WIP] Cmake builds libgit2 Cmake builds libgit2 and --pull_hf_mode for ovms Apr 11, 2025
@rasapala rasapala requested a review from dtrawins April 11, 2025 13:12
@@ -66,4 +66,10 @@ struct ModelsSettingsImpl {
std::string configPath;
};

struct HFSettingsImpl {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why separate structure instead of nesting this inside server settings?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This structure will grow and the settings are not about server functionality.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can nest the new structure in server settings as agreed on sync.

#include "logging.hpp"
#include "server.hpp"
#include "status.hpp"
#include "libgt2/libgt2.hpp"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

external dependencies should be before ovms headers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"libgt2/libgt2.hpp" is our wrapper implementation.

Comment on lines 41 to 42
void setSourceModel(std::string inSourceModel);
void setRepositoryPath(std::string inRepoPath);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we set repo path once per start as well as source mode. Why do we need setters here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove them now.

int cloneRepository();
void setSourceModel(std::string inSourceModel);
void setRepositoryPath(std::string inRepoPath);
void setPullHfModelMode(bool isOn);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't create HfDownloader anyway if we don't pull so why we change mode?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option can be used in the future. We can remove setter though.

this->repoUrl = "";
}

HfDownloader::HfDownloader(const HfDownloader& hfDownloader) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need cpy constructor? If we need default then = default; should suffice here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed anymore.

Comment on lines +181 to +193
bool HfDownloader::CheckIfProxySet() {
const char* envCred = std::getenv("https_proxy");
if (!envCred)
return false;
return true;
}

bool HfDownloader::CheckIfTokenSet() {
const char* envCred = std::getenv("HF_TOKEN");
if (!envCred)
return false;
return true;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are not methods but utility functions here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly connected and used in the class. Can we keep them as private?

Comment on lines 209 to 226
void HfDownloader::SetHfEndpoint() {
const char* envCred = std::getenv("HF_ENDPOINT");
this->hfEndpoint = "huggingface.co";
if (envCred) {
this->hfEndpoint = std::string(envCred);
} else {
printf("Info: HF_ENDPOINT environment variable not set.\n");
}

if (!endsWith(this->hfEndpoint, "/")) {
this->hfEndpoint.append("/");
}
}

void HfDownloader::UpdateRepoUrl() {
this->repoUrl = "https://";
this->repoUrl += this->hfEndpoint + this->sourceModel;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hfEndpoint is used only to create repo url so this does not need to be a member. We don't need to store it as state after cloning repository. Same is true for repoUrl

return true;
}

void HfDownloader::GetRepositoryUrlWithPassword(std::string& passRepoUrl) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take endpoint & source model as argument. Return passRepoUrl instead of passing ref.

state = ModuleState::STARTED_INITIALIZE;
SPDLOG_INFO("{} starting", HF_MODEL_PULL_MODULE_NAME);

this->hfDownloader = std::make_unique<HfDownloader>(config.getHfSettings().sourceModel, config.getHfSettings().repoPath, config.getHfSettings().pullHfModelMode);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put HfSettings as a member of server settings.
Why pass all settings separatelly when we can pass them all at once?

Addiditonally I would consider checking for ENV variables here and passing content below for easier (less intertwined testing). You cannot now verify different behavior with different env variables at the level of module.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module will have clone methods. This can be tested for env settings.

commit = "338e6fb681369ff0537719095e22ce9dc602dbf0", # Dec 28, 2024 - v1.9.0
build_file = "@_libgt2_engine//:BUILD",
patch_args = ["-p1"],
patches = ["lfs.patch"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put commend here why this patch is needed

@@ -2712,6 +2715,7 @@ cc_test(
"test/pipelinedefinitionstatus_test.cpp",
"test/predict_validation_test.cpp",
"test/prediction_service_test.cpp",
"test/pull_hf_model_test.cpp",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

separate test target. check eg openvino_tests/openvino_remote_tensor_tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is standard tests, does not require additional settings nor dependencies.

while ((server.getModuleState(ovms::HF_MODEL_PULL_MODULE_NAME) != ovms::ModuleState::SHUTDOWN) &&
(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - start).count() < timeoutSeconds)) {
}
ASSERT_EQ(server.getModuleState(ovms::HF_MODEL_PULL_MODULE_NAME), ovms::ModuleState::SHUTDOWN) << "OVMS did not download model in allowed time:" << timeoutSeconds << "s. Check machine load";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ASSERT_EQ(server.getModuleState(ovms::HF_MODEL_PULL_MODULE_NAME), ovms::ModuleState::SHUTDOWN) << "OVMS did not download model in allowed time:" << timeoutSeconds << "s. Check machine load";
ASSERT_EQ(server.getModuleState(ovms::HF_MODEL_PULL_MODULE_NAME), ovms::ModuleState::SHUTDOWN) << "OVMS did not download model in allowed time:" << timeoutSeconds << "s. Check machine & network load";

@@ -696,6 +702,30 @@ void EnsureServerStartedWithTimeout(ovms::Server& server, int timeoutSeconds) {
ASSERT_EQ(server.getModuleState(ovms::SERVABLE_MANAGER_MODULE_NAME), ovms::ModuleState::INITIALIZED) << "OVMS did not fully load until allowed time:" << timeoutSeconds << "s. Check machine load";
}

void EnsureServerModelDownloadFinishedWithTimeout(ovms::Server& server, int timeoutSeconds) {
auto start = std::chrono::high_resolution_clock::now();
while ((server.getModuleState(ovms::HF_MODEL_PULL_MODULE_NAME) != ovms::ModuleState::SHUTDOWN) &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be != AVAILABLE?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module shutdowns after clone() is executed.

Comment on lines 42 to 48
state = ModuleState::INITIALIZED;
SPDLOG_INFO("{} started", HF_MODEL_PULL_MODULE_NAME);

status = this->hfDownloader->cloneRepository();
if (!status.ok()) {
return status;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
state = ModuleState::INITIALIZED;
SPDLOG_INFO("{} started", HF_MODEL_PULL_MODULE_NAME);
status = this->hfDownloader->cloneRepository();
if (!status.ok()) {
return status;
}
SPDLOG_INFO("{} started", HF_MODEL_PULL_MODULE_NAME);
status = this->hfDownloader->cloneRepository();
if (!status.ok()) {
return status;
}
state = ModuleState::INITIALIZED;

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants