Skip to content

Commit 7f39544

Browse files
authored
Enhance the flexibility of the c streamer (#1940)
This PR is aimed at increasing the flexibility of the c streamer for llm generation. In C++, a streamer can add additional functionality through lambda captures (e.g. https://github.com/openvinotoolkit/model_server/blob/f513c50d45874392f0c6f356484c89003fb47dcc/src/llm/servable.cpp#L66). Therefore, an extra `void*` parameter is added to the C streamer to align with the C++ streamer.
1 parent 2b9a344 commit 7f39544

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

samples/c/text_generation/chat_sample_c.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@
88
#include "openvino/genai/c/llm_pipeline.h"
99

1010
#define MAX_PROMPT_LENGTH 64
11-
#define MAX_OUTPUT_LENGTH 1024
1211

1312
#define CHECK_STATUS(return_status) \
1413
if (return_status != OK) { \
1514
fprintf(stderr, "[ERROR] return status %d, line %d\n", return_status, __LINE__); \
1615
goto err; \
1716
}
18-
19-
ov_genai_streamming_status_e print_callback(const char* args) {
20-
if (args) {
21-
fprintf(stdout, "%s", args);
17+
ov_genai_streamming_status_e print_callback(const char* str, void* args) {
18+
if (str) {
19+
// If args is not null, it needs to be cast to its actual type.
20+
fprintf(stdout, "%s", str);
2221
fflush(stdout);
2322
return OV_GENAI_STREAMMING_STATUS_RUNNING;
2423
} else {
@@ -37,7 +36,8 @@ int main(int argc, char* argv[]) {
3736

3837
ov_genai_generation_config* config = NULL;
3938
ov_genai_llm_pipeline* pipeline = NULL;
40-
stream_callback streamer = &print_callback;
39+
streamer_callback streamer;
40+
streamer.callback_func = print_callback;
4141
char prompt[MAX_PROMPT_LENGTH];
4242

4343
CHECK_STATUS(ov_genai_llm_pipeline_create(models_path, device, &pipeline));

src/c/include/openvino/genai/c/llm_pipeline.h

+11-3
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,17 @@ typedef enum {
9696
} ov_genai_streamming_status_e;
9797

9898
/**
99-
* @brief Callback function for streaming output.
99+
* @brief Structure for streamer callback functions with arguments.
100+
*
101+
* The callback function takes two parameters:
102+
* - `const char* str`: A constant string extracted from the decoded result for processing
103+
* - `void* args`: A pointer to additional arguments, allowing flexible data passing.
100104
*/
101-
typedef ov_genai_streamming_status_e(OPENVINO_C_API_CALLBACK* stream_callback)(const char*);
105+
typedef struct {
106+
ov_genai_streamming_status_e(
107+
OPENVINO_C_API_CALLBACK* callback_func)(const char* str, void* args); //!< Pointer to the callback function
108+
void* args; //!< Pointer to the arguments passed to the callback function
109+
} streamer_callback;
102110

103111
/**
104112
* @brief Generate results by ov_genai_llm_pipeline
@@ -114,7 +122,7 @@ typedef ov_genai_streamming_status_e(OPENVINO_C_API_CALLBACK* stream_callback)(c
114122
OPENVINO_GENAI_C_EXPORTS ov_status_e ov_genai_llm_pipeline_generate(ov_genai_llm_pipeline* pipe,
115123
const char* inputs,
116124
const ov_genai_generation_config* config,
117-
const stream_callback* streamer,
125+
const streamer_callback* streamer,
118126
ov_genai_decoded_results** results);
119127
/**
120128
* @brief Start chat with keeping history in kv cache.

src/c/src/llm_pipeline.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void ov_genai_llm_pipeline_free(ov_genai_llm_pipeline* pipe) {
9090
ov_status_e ov_genai_llm_pipeline_generate(ov_genai_llm_pipeline* pipe,
9191
const char* inputs,
9292
const ov_genai_generation_config* config,
93-
const stream_callback* streamer,
93+
const streamer_callback* streamer,
9494
ov_genai_decoded_results** results) {
9595
if (!pipe || !(pipe->object) || !inputs || !(streamer || results)) {
9696
return ov_status_e::INVALID_C_PARAM;
@@ -102,7 +102,7 @@ ov_status_e ov_genai_llm_pipeline_generate(ov_genai_llm_pipeline* pipe,
102102
ov::genai::StringInputs input = {input_str};
103103
if (streamer) {
104104
auto callback = [streamer](std::string word) -> ov::genai::StreamingStatus {
105-
return static_cast<ov::genai::StreamingStatus>((*streamer)(word.c_str()));
105+
return static_cast<ov::genai::StreamingStatus>((streamer->callback_func)(word.c_str(), streamer->args));
106106
};
107107
*(_results->object) = (config && config->object)
108108
? pipe->object->generate(input, *(config->object), callback)

0 commit comments

Comments
 (0)