Skip to content
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

llmodel: dont load libs in static initialization #1546

Closed
wants to merge 1 commit into from
Closed

Conversation

apage43
Copy link
Member

@apage43 apage43 commented Oct 21, 2023

this fixes some issues that were being seen on installed windows builds of 2.5.0

setImplementationsSearchPath did not work if llmodel was initialized before it was called

  • do not actually load impl dlls in the static initializer, wait until we're actually trying to load a model for the first time

  • rescan on the next model load attempt if the search path has been changed

  • only load dlls that actually might be model impl dlls, otherwise we pull all sorts of random junk into the process before it might expect to be

@cosmic-snow
Copy link
Collaborator

Tried it again in the following combination of configurations and so far I didn't see any problems like in v2.5.0:

  • Inside Qt Creator (Run Without Deployment) and a locally prepared offline installer
  • Debug build and RelWithDebInfo

static auto* libs = new std::vector<Implementation>([] () {
std::vector<Implementation> fres;

if(!s_scanned) {
Copy link
Member

Choose a reason for hiding this comment

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

s_impl_libs should be a function-local static.

If we're at all concerned about thread safety, we should use a function to compute s_impl_libs and initialize it on the same line as the declaration - C++ guarantees that the initializer will be run only once. Otherwise, we should at least put if (s_scanned) { return s_impl_libs; } at the top to reduce the indentation level.

Copy link
Member Author

Choose a reason for hiding this comment

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

moving the decl/init into the fn, but the whole thing here is that we can't actually compute it (do the dlopen, etc.) at static init time because the search path may not actually be set yet (in the GUI case at least it is set by a different static initializer in a different file and it sometimes worked if that one ran first, but it is not guaranteed that it will)

if we want to actually be threadsafe around this we can't have a global mutable search path

Copy link
Member

Choose a reason for hiding this comment

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

Static local variables are not initialized until the first time control passes through their declaration. See cppreference.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's chat about this. From what I can tell, you're both right. It should be static local, but the problem remains if that function is called before the global search path is set?

Copy link
Member Author

@apage43 apage43 Oct 23, 2023

Choose a reason for hiding this comment

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

Yeahh either way if the method to set the search path is used it needs to have the re-checking behavior if it's not clearly documented to be useless unless called very early

I am not really clear on how this had been being called before that but I definitely caught this code running and loading libs before the chat gui had changed the path from the default .

Copy link
Member

@cebtenzzre cebtenzzre Oct 23, 2023

Choose a reason for hiding this comment

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

Why does the chat client call setImplementationsSearchPath in the constructor of LLM instead of main.cpp?

And I think it would be a good idea to guard this code with a mutex (including the setting of s_scanned to false) in case it is called from more than one thread.

Copy link
Member Author

@apage43 apage43 Oct 23, 2023

Choose a reason for hiding this comment

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

hmm, yeah, all the globalInstance()s should also be deferred til first use so should get run in the order they are called, and at least spot-checking it it does set the search path before its read when running from the build tree - built an installer to check and that also remains the case - so its likely the bigger culprit here was it dlopening dlls it shouldn't and that check is probably doing more work here than anything else

@cebtenzzre
Copy link
Member

For reference, here is a description of the issue this PR addresses:

with a model in the dir it fairly consistently reserves the ram for it and then crashes before the gui even opens

making an installer locally and installing it also causes this, but running the same binary out of the build tree works fine

gets as far as finishing deserializing chats but the gui never even opens.. sometimes it crashes immediately and sometimes it hangs and when it hangs all the deserializing chats messages show twice

this fixes some issues that were being seen on installed windows builds of 2.5.0

setImplementationsSearchPath did not work if llmodel was initialized before it was called

* do not actually load impl dlls in the static initializer, wait until we're actually trying to load a model for the first time

* rescan on the next model load attempt if the search path has been changed

* only load dlls that actually might be model impl dlls, otherwise we pull all sorts of random junk into the process before it might expect to be

Co-authored-by: cebtenzzre <[email protected]>
Signed-off-by: Aaron Miller <[email protected]>
@apage43
Copy link
Member Author

apage43 commented Oct 21, 2023

removed unnecessary unique_ptr wrapping that was only needed when I was attempting to stage the Implementations collected in a scan in a separate vector and move them over to the main one at the end

@apage43
Copy link
Member Author

apage43 commented Oct 23, 2023

#1556 fixes the issues I was encountering on its own, this (messing with the init order) probably isn't necessary

@apage43 apage43 closed this Oct 23, 2023
@cebtenzzre cebtenzzre deleted the dll-load branch February 10, 2025 16:56
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.

4 participants