vowpal_wabbit
vowpal_wabbit copied to clipboard
Vowpal Wabbit C API getting 0 as prediction
Describe the bug
I am trying to write a C program that loads a trained vw model and returns predictions in real time. For this, I am using libvw_c_wrapper and using methods described here.
The model was trained and saved with following configurations in python:
vw = vowpalwabbit.Workspace(
"--cats "
+ str(num_actions)
+ " --bandwidth "
+ str(bandwidth)
+ " --min_value {} --max_value {} --json --chain_hash --coin --epsilon 0.1".format(min_val, max_val)
And saved as: vw.save('nadwwadw.model')
This is my C program (vw_client.c):
#include "/Users/../C_VW_Test/vwdll.h"
#include <stdio.h>
int main()
{
VW_HANDLE vw;
char vw_arg[] = "-i nadwwadw.model";
vw = VW_InitializeA(vw_arg);
char vw_example[] = "ca | ";
for (int i=0; i<1000 ; i++) {
VW_EXAMPLE example = VW_ReadExampleA(vw, vw_example);
float pred = VW_Predict(vw, example);
printf("VW_Predict: %f\n", pred);
}
return 0;
}
and compile using gcc vw_client.c -L. -lvw_c_wrapper -o test
When I load this model in jupyter notebook as new_vw = vowpalwabbit.Workspace("-i nadwwadw.model")
and make predictions as new_vw.predict("ca | ")
, I get the output as (0.2624061703681946, 230.43333435058594).
However, my C code returns prediction as 0.00000 even for all iterations.
My requirements involve only predictions for now.
Can someone please help me understand
- Why am i getting different results in C and how do I solve it?
- Am I using the correct dylib/so file? If no, steps to build the correct one.
Thanks in Advance
How to reproduce
Described above
Version
9.0.1
OS
MacOS
Language
C
Additional context
No response
The function VW_Predict
returns the scalar prediction, however, you need the pdf value prediction produced by continuous actions. Unfortunately this is not available from the C API you referenced.
The reason Python works is it automatically determines what prediction type is returned by a given VW workspace and returns the correct type.
In that case can you suggest any alternative. Even a C++ solution would work
So a C++ solution would look something like this (I haven't tested it):
auto* ws = VW::initialize("-i nadwwadw.model");
auto* ex = VW::read_example(*ws, "ca | ");
ws->predict(*ex);
auto& prediction = ex->pred.pdf_value;
VW::finish_example(*ex);
VW::finish(*ws);
Can you please provide some documentation/pointers on required .so/.a/.dylib and steps to build them inorder to use the above mentioned solution.
It's a bit out of date so may need some tweaking but generally speaking this is an example of what it may look like to have a C++ project depend on VW. Do note that when using the C++ interface directly some aspects of the API can change between releases. It does not have the same stability as the Python interface or command line. That being said we do our best to consider if a change is user facing and communicate accordingly in release notes and versioning.
https://github.com/lokitoth/vw_use_demo
I plan to add cats support in C Wrapper API, I did the following for a basic code check:
-
Added
VW_DLL_PUBLIC void VW_CALLING_CONV Print() {printf("Random\n");}
in vowpal_wabbit/vowpalwabbit/c_wrapper/src/vwdll.cc -
Added
VW_DLL_PUBLIC void VW_CALLING_CONV Print();
in vowpal_wabbit/vowpalwabbit/c_wrapper/include/vw/c_wrapper/vwdll.h -
Build using
cd vowpal_wabbit
->cmake -S . -B build
->cd build
->make vw_c_wrapper
-
Add dylib Try to run Print() in code mentioned in C issue using same method. However I get the following error:
dyld: lazy symbol binding failed: Symbol not found: _Print
Referenced from: /Users/bhavya.sa/Desktop/C_VW_Test/./a.out
Expected in: /usr/local/lib/libvw_c_wrapper.dylib
dyld: Symbol not found: _Print
Referenced from: /Users/bhavya.sa/Desktop/C_VW_Test/./a.out
Expected in: /usr/local/lib/libvw_c_wrapper.dylib
zsh: abort ./a.out
[Update] https://github.com/VowpalWabbit/vowpal_wabbit/pull/4021
I was able to solve the issue by making changes mentioned in above pull request and building the exact same way. Before running, add the lib_vw_c_wrapper.dylib to $LD_LIBRARY_PATH variable: ```export LD_LIBRARY_PATH=<path_to_lib_vw_c_wrapper>:LD_LIBRARY_PATH
Is there any way we can read json format using C/C++ APIs for cats mode ?
@jackgerrits
Provided the VW instance has been initialized to use --json
, then you can look at how Python reads text input:
https://github.com/VowpalWabbit/vowpal_wabbit/blob/d00835a4f3edee4f30195da92a7021a7f663fd03/python/pylibvw.cc#L560
Support for the CATS pdf value prediction type was merged in this PR: https://github.com/VowpalWabbit/vowpal_wabbit/pull/4021
Closing as I think this is resolved now. Please feel free to open a new issue if you face issues.