It is impossible to load a model from a buffer (e.g. bytestring) in Python, due to a bug where ctypes is used incorrectly to get a const char*
pointer:
>>> bst.load_model(b'123')
TypeError: underlying buffer is not writable
Here's a short example of what it is basically trying to do:
>>> b = b'123'
>>> (ctypes.c_char * 3).from_buffer(buf)
TypeError: underlying buffer is not writable
See also: #542
Basically, instead of using .from_buffer()
, you should use .from_buffer_copy()
which only requires readability.
However, apparently, there is some problem with XGBoosterLoadModelFromBuffer()
as it segfaults if you provide it with the dump buffer.
Here's a modified version that uses read-only buffer:
import ctypes
import xgboost
import xgboost.core
def xgb_load_model(buf):
if isinstance(buf, str):
buf = buf.encode()
bst = xgboost.core.Booster()
n = len(buf)
length = xgboost.core.c_bst_ulong(n)
ptr = (ctypes.c_char * n).from_buffer_copy(buf)
xgboost.core._check_call(
xgboost.core._LIB.XGBoosterLoadModelFromBuffer(bst.handle, ptr, length)
) # segfault
return bst
Consolidating to #3439. This issue should be re-opened if you or others decide to actively work on implementing this feature.
Most helpful comment
However, apparently, there is some problem with
XGBoosterLoadModelFromBuffer()
as it segfaults if you provide it with the dump buffer.Here's a modified version that uses read-only buffer: