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

Support non-json serializable objects in LLMContext #1589

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
46bd47e
Revert to returning the exception rather than an error string
dagardner-nv Mar 14, 2024
bb3fa5c
WIP
dagardner-nv Mar 15, 2024
e2db600
Update testt, inside of LLMContext::pop() are three if/else branches,…
dagardner-nv Mar 15, 2024
63112e1
Add new overrides for set_output
dagardner-nv Mar 25, 2024
5e5723b
Remove unused values member
dagardner-nv Mar 25, 2024
ec19a84
WIP
dagardner-nv Mar 25, 2024
413d92c
Add find_input method
dagardner-nv Mar 25, 2024
7b4d82f
Overload push and pop
dagardner-nv Mar 25, 2024
fd37364
Fix return type
dagardner-nv Mar 25, 2024
a1e435b
Remove leading / prior to fetching, ensure we have the gil when we ne…
dagardner-nv Mar 25, 2024
91c1023
Cast the context and use the python version of set_output
dagardner-nv Mar 25, 2024
b344ef4
Use a type hint so VSCode won't warn that df is None
dagardner-nv Mar 25, 2024
1e7efc3
Inform python bindings of the base class
dagardner-nv Mar 25, 2024
fec0e9b
Ensure we get a python context when we need one
dagardner-nv Mar 25, 2024
38450a3
Use get_python to ensure nested objects are fetched
dagardner-nv Mar 26, 2024
b225573
Remove unnecessary caching
dagardner-nv Mar 26, 2024
e34b05a
Remove redundant json methods
dagardner-nv Mar 26, 2024
07e4e48
Update stub
dagardner-nv Mar 26, 2024
6b307fa
replace usage of dynamic_pointer_cast with MRC_PTR_CAST
dagardner-nv Mar 27, 2024
026497e
wip
dagardner-nv Mar 27, 2024
4cd7280
Adopt nlohmann_json 3.11
dagardner-nv Apr 1, 2024
4015df7
WIP
dagardner-nv Apr 1, 2024
c1c8bad
WIP
dagardner-nv Apr 1, 2024
4514fae
Remove py wrappers, instead define a pybind11 cast
dagardner-nv Apr 1, 2024
98c4ee4
Uncomment LLMContext mapping
dagardner-nv Apr 1, 2024
981bd3b
Pybind caster for jsonvalues
dagardner-nv Apr 2, 2024
151c275
Python None should be a json null
dagardner-nv Apr 2, 2024
894857c
WIP
dagardner-nv Apr 2, 2024
57389fa
WIP: Tests compiling now
dagardner-nv Apr 2, 2024
98b2fbe
Fix impl for get_inputs
dagardner-nv Apr 2, 2024
ec86809
WIP
dagardner-nv Apr 2, 2024
ce95294
Add debug launch for running test_llm.x
dagardner-nv Apr 2, 2024
da46791
Fix get_inputs
dagardner-nv Apr 2, 2024
bd855eb
C++ tests passing, need to move ensure_leading_path logic to MRC
dagardner-nv Apr 2, 2024
267f972
Move ensure_leading_path logic to MRC
dagardner-nv Apr 2, 2024
13d254a
Updated stub
dagardner-nv Apr 2, 2024
4db9414
Comment out the gtest filter
dagardner-nv Apr 2, 2024
8e3a8c4
Fix bug in cast method by performing a release. Fix out of date docst…
dagardner-nv Apr 2, 2024
7c6cd3d
Fix docstring
dagardner-nv Apr 3, 2024
6211dca
Replace referneces to 'inty' with json
dagardner-nv Apr 3, 2024
afbed00
Merge branch 'branch-24.06' of github.com:nv-morpheus/Morpheus into d…
dagardner-nv Apr 3, 2024
dc8d1ba
IWYU fixes
dagardner-nv Apr 3, 2024
91fc96d
IWYU fixes
dagardner-nv Apr 3, 2024
c557c6d
IWYU fixes
dagardner-nv Apr 3, 2024
112a405
IWYU fixes
dagardner-nv Apr 3, 2024
8f24c05
Revert marking push and pop as virtual
dagardner-nv Apr 3, 2024
716662d
Remove unneeded create_context method
dagardner-nv Apr 3, 2024
7ccdc09
Update docstrings
dagardner-nv Apr 3, 2024
30317c1
Remove nlohmann::json overloads of set_output, since nlohmann::json i…
dagardner-nv Apr 3, 2024
2593ad9
Remove unused pybind headers
dagardner-nv Apr 3, 2024
f4d6baa
IWYU fixes
dagardner-nv Apr 3, 2024
03da2fc
Move type-caster for json_values to MRC
dagardner-nv Apr 3, 2024
16b2e60
Remove unused code
dagardner-nv Apr 5, 2024
b1e2c01
Merge branch 'branch-24.06' of github.com:nv-morpheus/Morpheus into d…
dagardner-nv Apr 5, 2024
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
2 changes: 1 addition & 1 deletion conda/environments/all_cuda-121_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ dependencies:
- networkx=2.8.8
- newspaper3k=0.2
- ninja=1.11
- nlohmann_json=3.9
- nlohmann_json=3.11
- nodejs=18.*
- numexpr
- numpydoc=1.5
Expand Down
2 changes: 1 addition & 1 deletion conda/environments/dev_cuda-121_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ dependencies:
- nbsphinx
- networkx=2.8.8
- ninja=1.11
- nlohmann_json=3.9
- nlohmann_json=3.11
- nodejs=18.*
- numpydoc=1.5
- nvtabular=23.08.00
Expand Down
2 changes: 1 addition & 1 deletion dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ dependencies:
- librdkafka>=1.9.2,<1.10.0a0
- mrc=24.03
- ninja=1.11
- nlohmann_json=3.9
- nlohmann_json=3.11
- pkg-config=0.29 # for mrc cmake
- protobuf=4.24
- pybind11-stubgen=0.10.5
Expand Down
28 changes: 28 additions & 0 deletions morpheus.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,34 @@
},
"type": "cppdbg"
},
{
"MIMode": "gdb",
"args": [
// Uncomment to run a specific test
// "--gtest_filter='TestLLMContext.PopSelectMultipleOutputs'"
],
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "GLOG_v",
"value": "10"
}
],
"externalConsole": false,
"miDebuggerPath": "gdb",
"name": "Debug LLM C++ Tests",
"program": "${workspaceFolder}/build/morpheus/_lib/tests/test_llm.x",
"request": "launch",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"ignoreFailures": true,
"text": "-enable-pretty-printing"
}
],
"stopAtEntry": false,
"type": "cppdbg"
},
{
"args": [
"--input_file=validation.csv",
Expand Down
39 changes: 22 additions & 17 deletions morpheus/_lib/include/morpheus/llm/llm_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
#pragma once

#include "morpheus/export.h"
#include "morpheus/llm/fwd.hpp" // for ControlMessage
#include "morpheus/llm/input_map.hpp"
#include "morpheus/llm/llm_task.hpp"
#include "morpheus/messages/control.hpp"
#include "morpheus/utilities/json_types.hpp"

#include <mrc/types.hpp>
#include <nlohmann/json.hpp>
#include <pymrc/utilities/json_values.hpp>

#include <memory>
#include <string>
Expand All @@ -36,7 +35,6 @@ struct LLMContextState
{
LLMTask task;
std::shared_ptr<ControlMessage> message;
nlohmann::json values;
};

/**
Expand Down Expand Up @@ -110,11 +108,11 @@ class MORPHEUS_EXPORT LLMContext : public std::enable_shared_from_this<LLMContex
std::shared_ptr<ControlMessage>& message() const;

/**
* @brief Get all output mappings for this context.
* @brief Get all outputs for this context.
*
* @return nlohmann::json::const_reference
* @return const mrc::pymrc::JSONValues&
*/
nlohmann::json::const_reference all_outputs() const;
const mrc::pymrc::JSONValues& all_outputs() const;

/**
* @brief Get full name of context containing parents up to root.
Expand Down Expand Up @@ -142,39 +140,39 @@ class MORPHEUS_EXPORT LLMContext : public std::enable_shared_from_this<LLMContex
/**
* @brief Get the input value from parent context corresponding to first internal input of this context.
*
* @return nlohmann::json::const_reference
* @return mrc::pymrc::JSONValues
*/
nlohmann::json::const_reference get_input() const;
mrc::pymrc::JSONValues get_input() const;

/**
* @brief Get the parent output value corresponding to given internal input name.
*
* @param node_name internal input name
* @return nlohmann::json::const_reference
* @return mrc::pymrc::JSONValues
*/
nlohmann::json::const_reference get_input(const std::string& node_name) const;
mrc::pymrc::JSONValues get_input(const std::string& node_name) const;

/**
* @brief Get parent output values corresponding to all internal input names.
*
* @return nlohmann::json
* @return mrc::pymrc::JSONValues
*/
nlohmann::json get_inputs() const;
mrc::pymrc::JSONValues get_inputs() const;

/**
* @brief Set output mappings for this context.
*
* @param outputs output mappings
*/
void set_output(nlohmann::json outputs);
void set_output(mrc::pymrc::JSONValues&& outputs);

/**
* @brief Set an output value for this context.
*
* @param output_name output name
* @param output output value
*/
void set_output(const std::string& output_name, nlohmann::json output);
void set_output(const std::string& output_name, mrc::pymrc::JSONValues&& output);

/**
* @brief Set the output names to propagate from this context when using pop.
Expand All @@ -185,17 +183,24 @@ class MORPHEUS_EXPORT LLMContext : public std::enable_shared_from_this<LLMContex

void outputs_complete();

nlohmann::json::const_reference view_outputs() const;
/**
* @brief Get all outputs for this context.
*
* @return const mrc::pymrc::JSONValues&
*/
const mrc::pymrc::JSONValues& view_outputs() const;

private:
input_mappings_t::const_iterator find_input(const std::string& node_name, bool throw_if_not_found = true) const;

std::shared_ptr<LLMContext> m_parent{nullptr};
std::string m_name;
input_mappings_t m_inputs;
std::vector<std::string> m_output_names; // Names of keys to be used as the output. Empty means use all keys

std::shared_ptr<LLMContextState> m_state;

nlohmann::json m_outputs;
mrc::pymrc::JSONValues m_outputs;

mrc::Promise<void> m_outputs_promise;
mrc::SharedFuture<void> m_outputs_future;
Expand Down
5 changes: 1 addition & 4 deletions morpheus/_lib/include/morpheus/llm/llm_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@
#pragma once

#include "morpheus/export.h"
#include "morpheus/llm/fwd.hpp"
#include "morpheus/llm/fwd.hpp" // for ControlMessage, LLMContext, LLMTask, LLMTaskHandler, LLMTaskHandlerRunner
#include "morpheus/llm/input_map.hpp"
#include "morpheus/llm/llm_context.hpp"
#include "morpheus/llm/llm_node.hpp"
#include "morpheus/llm/llm_task_handler.hpp"
#include "morpheus/messages/control.hpp"
#include "morpheus/types.hpp"

#include <memory>
Expand Down
4 changes: 2 additions & 2 deletions morpheus/_lib/include/morpheus/llm/llm_lambda_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class LLMLambdaNode : public LLMNodeBase
{
const auto& arg = context->get_input();

auto output = co_await this->m_function(arg.get<std::tuple_element_t<0, args_tuple_t>>());
auto output = co_await this->m_function(arg.view_json().get<std::tuple_element_t<0, args_tuple_t>>());

nlohmann::json outputs_json = std::move(output);

Expand All @@ -91,7 +91,7 @@ class LLMLambdaNode : public LLMNodeBase
{
auto args = context->get_inputs();

auto outputs = co_await this->m_function(args);
auto outputs = co_await this->m_function(args.view_json());

nlohmann::json outputs_json = std::move(outputs);

Expand Down
35 changes: 18 additions & 17 deletions morpheus/_lib/include/morpheus/pybind11/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,36 @@ struct type_caster<nlohmann::json>
{
public:
/**
* This macro establishes the name 'inty' in
* function signatures and declares a local variable
* 'value' of type inty
* This macro establishes a local variable 'value' of type nlohmann::json
*/
PYBIND11_TYPE_CASTER(nlohmann::json, _("object"));

/**
* Conversion part 1 (Python->C++): convert a PyObject into a inty
* Conversion part 1 (Python->C++): convert a PyObject into an nlohmann::json
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
bool load(handle src, bool convert)
{
if (!src || src.is_none())
if (!src)
{
return false;
}

value = mrc::pymrc::cast_from_pyobject(pybind11::reinterpret_borrow<pybind11::object>(src));
if (src.is_none())
{
value = nlohmann::json(nullptr);
}
else
{
value = mrc::pymrc::cast_from_pyobject(pybind11::reinterpret_borrow<pybind11::object>(src));
}

return true;
}

/**
* Conversion part 2 (C++ -> Python): convert an inty instance into
* Conversion part 2 (C++ -> Python): convert an nlohmann::json instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
Expand All @@ -76,14 +81,12 @@ struct type_caster<nlohmann::json_dict>
{
public:
/**
* This macro establishes the name 'inty' in
* function signatures and declares a local variable
* 'value' of type inty
* This macro establishes a local variable 'value' of type nlohmann::json_dict
*/
PYBIND11_TYPE_CASTER(nlohmann::json_dict, _("dict[str, typing.Any]"));

/**
* Conversion part 1 (Python->C++): convert a PyObject into a inty
* Conversion part 1 (Python->C++): convert a PyObject into an nlohmann::json_dict
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
Expand All @@ -106,7 +109,7 @@ struct type_caster<nlohmann::json_dict>
}

/**
* Conversion part 2 (C++ -> Python): convert an inty instance into
* Conversion part 2 (C++ -> Python): convert an nlohmann::json_dict instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
Expand All @@ -123,14 +126,12 @@ struct type_caster<nlohmann::json_list>
{
public:
/**
* This macro establishes the name 'inty' in
* function signatures and declares a local variable
* 'value' of type inty
* This macro establishes a local variable 'value' of type nlohmann::json_list
*/
PYBIND11_TYPE_CASTER(nlohmann::json_list, _("list[typing.Any]"));

/**
* Conversion part 1 (Python->C++): convert a PyObject into a inty
* Conversion part 1 (Python->C++): convert a PyObject into an nlohmann::json_list
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
Expand All @@ -153,7 +154,7 @@ struct type_caster<nlohmann::json_list>
}

/**
* Conversion part 2 (C++ -> Python): convert an inty instance into
* Conversion part 2 (C++ -> Python): convert an nlohmann::json_list instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
Expand Down
4 changes: 2 additions & 2 deletions morpheus/_lib/llm/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class LLMContext():
def get_input(self) -> object: ...
@typing.overload
def get_input(self, node_name: str) -> object: ...
def get_inputs(self) -> dict: ...
def get_inputs(self) -> object: ...
def message(self) -> morpheus._lib.messages.ControlMessage: ...
def push(self, name: str, inputs: typing.List[InputMap]) -> LLMContext: ...
@typing.overload
Expand Down Expand Up @@ -210,7 +210,7 @@ class LLMTaskHandler():
def __init__(self) -> None: ...
def get_input_names(self) -> typing.List[str]:
"""
Get the input names for the task handler.
Get the input names for the task handler.

Returns
-------
Expand Down
2 changes: 1 addition & 1 deletion morpheus/_lib/llm/include/py_llm_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "py_llm_node.hpp"

#include "morpheus/llm/fwd.hpp"
#include "morpheus/llm/fwd.hpp" // for LLMTaskHandler, ControlMessage, LLMContext, LLMEngine, LLMTask
#include "morpheus/llm/input_map.hpp"
#include "morpheus/llm/llm_engine.hpp"

Expand Down
2 changes: 1 addition & 1 deletion morpheus/_lib/llm/include/py_llm_lambda_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#pragma once

#include "morpheus/llm/llm_context.hpp"
#include "morpheus/llm/fwd.hpp" // for LLMContext
#include "morpheus/llm/llm_node_base.hpp"
#include "morpheus/types.hpp"

Expand Down
Loading
Loading