On Wednesday, 12 June 2024 at 17:00:14 UTC, Vinod K Chandran wrote:
>On Wednesday, 12 June 2024 at 10:16:26 UTC, Sergey wrote:
>Btw are you going to use PyD or doing everything manually from scratch?
Does PyD active now ? I didn't tested it. My approach is using "ctypes" library with my dll. Ctypes is the fastes FFI in my experience. I tested Cython, Pybind11 and CFFI. But None can beat the speed of ctypes. Currently the fastest experiments were the dlls created in Odin & C3. Both are non-GC languages.
It is probably not that well maintained, but it definitely works with python 3.10 and maybe even 3.11, i use it to interface with pytorch and numpy and PIL, but my use case is pretty simple, i just write some wrapper python functions to run inference and pass images back and forth using embedded py_stmts. the only problem is that it seems to leak a lot PydObjects so i have to manually free them, even scope doesn't helps with that which is sad.
example classifier python
def inference(image: Image):
""" Predicts the image class and returns confidences for every class
To get the class one can use the following code
> conf = inference(image)
> index = conf.argmax()
> cls = classes[index]
"""
# this detector doesn't works with more than 3 channels
ch = len(image.getbands())
has_transparency = image.info.get('transparency', None) is not None
if ch > 3 or has_transparency:
image = image.convert("RGB")
image_tensor = prep_transform(image).float()
image_tensor = image_tensor.unsqueeze_(0)
# it is fast enough to run on CPU
#if torch.cuda.is_available():
# image_tensor.cuda()
with torch.inference_mode():
# NOTE: read the comment on model
output = model(image_tensor)
index = output.data.numpy()
return index
and some of D functions
ImageData aiGoesBrrrr(string path, int strength = 50) {
try {
if (!pymod)
py_stmts("import sys; sys.path.append('modules/xyz')");
initOnce!pymod(py_import("xyz.inference"));
if (!pymod.hasattr("model"))
pymod.model = pymod.method("load_model", "modules/xyz/pre_trained/weights.pth");
PydObject ipath = py(path);
scope(exit) destroy(ipath);
auto context = new InterpContext();
context.path = ipath;
context.py_stmts("
from PIL import Image
image = Image.open(path)
ch = len(image.getbands())
if ch > 3:
image = image.convert('RGB')
");
// signature: def run(model, imagepath, alpha=45) -> numpy.Array
PydObject output = pymod.method("run", pymod.model, context.image, 100-strength);
context.output = output;
scope(exit) destroy(output);
PydObject shape = output.getattr("shape");
scope(exit) destroy(shape);
// int n = ...;
int c = shape[2].to_d!int;
int w = shape[1].to_d!int;
int h = shape[0].to_d!int;
// numpy array
void* raw_ptr = output.buffer_view().item_ptr([0,0,0]);
ubyte* d_ptr = cast(ubyte*) raw_ptr;
ubyte[] d_img = d_ptr[0..h*w*c];
return ImageData(d_img.dup, h ,w ,c);
} catch (PythonException e) {
// oh no...
auto context = new InterpContext();
context.trace = new PydObject(e.traceback);
context.py_stmts("from traceback import format_tb; trace = format_tb(trace)");
printerr(e.py_message, "\n", context.trace.to_d!string);
}
return ImageData.init;