If you're mainstream: Go or Java. If you're edgy: Nim, Scala, or Crystal
All of those have much more sane type, build, and packaging systems.
@perl-people, was this a solved problem when Perl was big? Or is python walking the same roads?
If you're mainstream: Go or Java. If you're edgy: Nim, Scala, or Crystal
All of those have much more sane type, build, and packaging systems.
@perl-people, was this a solved problem when Perl was big? Or is python walking the same roads?
The recipe for the 'solved' deployment:
- a compiler that ships with a build tool (so building is homogenous in the community)
- a centralized or at least uniformly accessible package repository (so dependency acquisition is homogenous in the community)
- a common file format for describing dependencies (so dependency resolution is homogenous in the community)
- a common file format for locking dependency versions (so deployment can be done reliably without vendoring dependencies)
- optional but very nice: a tool for managing compiler versions so it's easy to switch/upgrade projects
Any programming language that has all of these boxes ticked is a modern programming language in my book. As far as I know Ruby is the first that ticked all of them, but other ones I've used that have this: Node.js, Go, Rust, Haskell, Python (though it's a bit messy). I'm pretty sure C# checks them as well nowadays, but I haven't used it in over 5 years so I'm not sure. Same for Java.I think a language should have its own official tooling that can achieve those without installing any external shit
There are quite a few of these. I couldn't do any of my ML work in a language other than Python or C++.
Calling what Go has a "type system" is a stretch IMO.
Overall looking at Python deployment story after using Elixir for the past couple of years makes me cringe a bit. Rather I have no idea how to do it. Deterministic versions, lock files, and container/tarball (or binary) support seems a given in 2020.
1: https://medium.com/@giovanni_94706/introducing-nimtorch-b8b0...
I don't follow - wouldn't nimtorch also require bundling pytorch on an embedded device?
See: https://pytorch.org/tutorials/advanced/cpp_frontend.html
I don't see the advantage of this setup over just loading a torchscript model in C++ or any other static language. A full set of bindings seems unnecessary unless you need to train in nim.
I prefer to avoid Python nowadays due to the pain of dependency management, a nice as this article is don't care to learn about Poetry. So training in pure C++ (or better Nim) is my preferred setup. Keeping a similar build setup for both training and deployment saves a lot of headaches which is why the nimtorch interface is handy even if it's not as full featured/up to date. Now I'm only deploying a very simple NN without much need for experimentation.
Deployment then just become:
- build zipapp - upload zipapp - ensure python interpretter - run zipapp
Which is just one more step than go.
Let's try an example with numpy:
$ py -m venv foo
$ foo\Scripts\activate
$ pip install numpy
$ code hello_numpy.py
# import numpy as np
# def main():
# print(np.arange(15).reshape(3, 5))
$ python hello_numpy.py
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
Now with shiv: $ copy hello_numpy.py foo\Lib\site-packages
$ shiv -e hello_numpy.main --site-packages test\Lib\site-packages\ -o hello_numpy.pyz
$ python hello_numpy.pyz
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
So it works fine, but remember:- it will only run on the system this particular numpy wheel has been designed to run on. In my case cp38-win_amd64.
- it will comes bundle with numpy. Numpy is quite big, which means your hello world pyz will be 14.1 Mo.
- it needs to unzip, so the first run will be slow