Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitccbea04

Browse files
committed
Edits
1 parent20b79f2 commitccbea04

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

‎pgml-docs/docs/blog/postgresml-is-moving-to-rust-for-our-2.0-release.md‎

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ image: https://postgresml.org/blog/images/abstraction.webp
55
image_alt:Moving from one abstraction layer to another.
66
---
77

8-
PostgresML ismoving to Rust for our 2.0release
8+
PostgresML isMoving to Rust for our 2.0Release
99
================================================
1010

1111
<pclass="author">
@@ -14,17 +14,17 @@ PostgresML is moving to Rust for our 2.0 release
1414
September 19, 2022
1515
</p>
1616

17-
PostgresML is a fairly young project. We recently released1.0 and now we're considering what we want to accomplish for2.0. In addition to simplifying the workflow for building models, we'd like to address runtime speed, memory consumption and the overall reliability we've seen for machine learning deployments running at scale.
17+
PostgresML is a fairly young project. We recently releasedv1.0 and now we're considering what we want to accomplish forv2.0. In addition to simplifying the workflow for building models, we'd like to address runtime speed, memory consumption and the overall reliability we've seen is needed for machine learning deployments running at scale.
1818

19-
Python is generally touted as fast enough for machine learning, and is the de facto industry standard with tons of popular libraries implementing all the latest and greatest algorithms. Many of these algorithms (torch, tensorflow, xgboost, numpy) have been optimized in C, but not all of them. For example, most of the[linear algorithms](https://github.com/scikit-learn/scikit-learn/tree/main/sklearn/linear_model) inscikit learnareimplemented in pure Python, although theyrely on numpy, which is a convenient optimization. It also usescython in a few performance critical places. This ecosystem has allowed PostgresML to offer a ton of functionality with minimal duplication of effort.
19+
Python is generally touted as fast enough for machine learning and is the de facto industry standard with tons of popular libraries, implementing all the latest and greatest algorithms. Many of these algorithms (Torch, Tensorflow, XGboost, NumPy) have been optimized in C, but not all of them. For example, most of the[linear algorithms](https://github.com/scikit-learn/scikit-learn/tree/main/sklearn/linear_model) inScikit-Learnarewritten in pure Python, although theydo use NumPy which is a convenient optimization. It also usesCython in a few performance critical places. This ecosystem has allowed PostgresML to offer a ton of functionality with minimal duplication of effort.
2020

2121

22-
##Ambitionstarts with asimple benchmark
22+
##AmbitionStarts With aSimple Benchmark
2323
<figure>
2424
<img alt="Ferris the crab" src="/blog/images/rust_programming_crab_sea.webp" />
2525
<figcaption>Rust mascot image by opensource.com</figcaption>
2626
</figure>
27-
To illustrate ourmotivation, we'll create a test set of 10,000 random embeddings with 128 dimensions, andstore them in a table. Our first benchmark will simulate semantic ranking, by computing the dot product against every member of the test set, sorting the results and returning the top match.
27+
To illustrate ourgoal, we created a test set of 10,000 random embeddings with 128 dimensions andstored them in a table. Our first benchmark will simulate semantic ranking, by computing the dot product against every member of the test set, sorting the results and returning the top match.
2828

2929
```sql linenums="1" title="generate_embeddings.sql"
3030
-- Generate 10,000 embeddings with 128 dimensions as FLOAT4[] type.
@@ -34,7 +34,7 @@ FROM generate_series(1, 1280000) i
3434
GROUP BY i %10000;
3535
```
3636

37-
Spoiler alert, idiomatic Rust is about 10x faster than native SQL,theembedded PL/pgSQL scripting language, andPython in this benchmark. Rust comes close to the handoptimized assembly version of the Basic Linear Algebra Subroutinesimplementation for the dot product. Numpy is supposed to provide optimizations in cases like this, but it's actually the worst performer. Data movement from Postgres to PL/Python is pretty good. It's even faster than the pure SQL equivalent, but adding the extra conversion from Python list to Numpy array takes almost as much time as everything else. Machine Learning systems that moverelativelylarge quantities of data around can become dominated by these extraneous operations, rather than the ML algorithms that actually generate value.
37+
Spoiler alert: idiomatic Rust is about 10x faster than native SQL, embedded PL/pgSQL, andpure Python. Rust comes close to the hand-optimized assembly version of the Basic Linear Algebra Subroutines(BLAS) implementation. NumPy is supposed to provide optimizations in cases like this but it's actually the worst performer. Data movement from Postgres to PL/Python is pretty good; it's even faster than the pure SQL equivalent, but adding the extra conversion from Python list to Numpy array takes almost as much time as everything else. Machine Learning systems that move large quantities of data around can become dominated by these extraneous operations rather than the ML algorithms that actually generate value.
3838

3939
<center>
4040
<iframe width="600" height="371" seamless frameborder="0" scrolling="no" src="https://docs.google.com/spreadsheets/d/e/2PACX-1vShmCVrYwmscys5TIo7c_C-1M3gE_GwENc4tTiU7A6_l3YamjJx7v5bZcafLIDcEIbFu-C2Buao4rQ6/pubchart?oid=815608582&amp;format=interactive"></iframe>
@@ -101,7 +101,7 @@ Spoiler alert, idiomatic Rust is about 10x faster than native SQL, the embedded
101101
ORDER BY 1
102102
LIMIT 1;
103103
```
104-
=== "Numpy"
104+
=== "NumPy"
105105
```sql linenums="1" title="define_numpy.sql"
106106
CREATE OR REPLACE FUNCTION dot_product_numpy(a FLOAT4[], b FLOAT4[])
107107
RETURNS FLOAT4
@@ -169,25 +169,29 @@ Spoiler alert, idiomatic Rust is about 10x faster than native SQL, the embedded
169169
LIMIT 1;
170170
```
171171

172-
We're building with the Rust[pgx](https://github.com/tcdi/pgx/tree/master/pgx) crate that makes our development cycle even nicer than the one we use to manage Python. It really streamlines creating an extension in Rust, so all we havetoworry about is writing our functions. It took about an hour to port all of our vector operations to Rust with BLAS support, and another week to port all the "business logic" for maintaining model training and deployment. We've even gained some new capabilities for caching models across connections (independent processes), nowthat we have accesstoPostgres shared memory, without having to worry about Python's GIL and GC. This is the dream of Apache's Arrow project, realizedforour applications, without having to change the world, just our implementations. 🤩 Single-copy end-to-end machine learning, with parallel processing and shared data access.
172+
After learning this, it should cometono surprisethat we're movingtoRustforPostgresML v2.0.
173173

174-
##What about XGBoost and friends?
175-
ML isn't just about basic math and a little bit of business logic. It's about all those complicated algorithms beyond linear regression for gradient boosting and deep learning. The good news is that most of these libraries are implemented in C/C++, and just have Python bindings. There are also bindings for Rust ([lightgbm](https://github.com/vaaaaanquish/lightgbm-rs),[xgboost](https://github.com/davechallis/rust-xgboost),[tensorflow](https://github.com/tensorflow/rust),[torch](https://github.com/LaurentMazare/tch-rs)).
174+
Our new extension will be built with the Rust[pgx](https://github.com/tcdi/pgx/tree/master/pgx) crate which makes our development cycle even nicer than the one we use to manage Python. It streamlined creating an extension in Rust, so all we have to worry about is writing our business logic. It took about an hour to port all of our vector operations to Rust with BLAS support, and another week to port all the rest needed for maintaining model training and deployment. Now that we have access to Postgres' shared memory, we've even gained some new capabilities such as caching models across connections (independent processes), without having to worry about Python's GIL and garbage collector. This is the dream of Apache's Arrow project, realized for our applications, without having to change the world, just our implementations: single-copy end-to-end machine learning, with parallel processing and shared data access. 🤩.
175+
176+
##What About XGBoost and Friends?
177+
ML isn't just about basic math and a little bit of business logic. It's about all those complicated algorithms beyond linear regression for gradient boosting and deep learning. The good news is that most of these libraries are implemented in C/C++ and just have Python bindings. There are also bindings for Rust ([lightgbm](https://github.com/vaaaaanquish/lightgbm-rs),[xgboost](https://github.com/davechallis/rust-xgboost),[tensorflow](https://github.com/tensorflow/rust),[torch](https://github.com/LaurentMazare/tch-rs)).
176178

177179
<figure>
178180
<imgalt="It's all abstraction"src="/blog/images/abstraction.webp" />
179181
<figcaption>Layers of abstraction must remain a good value.</figcaption>
180182
</figure>
181183

182-
The results are somewhat staggering. We didn't spend any time intentionally optimizing Rust over Python. Most of the time spent was just trying to get things to compile. 😅 It's hard to believe the difference is this big, but those fringe operations outside of the core machine learning algorithms really do dominate, requiring up to 35x more time in Python during inference. The difference between classification and regression speeds here are related to the dataset size. The scikit learn handwritten image classification dataset effectively has 64 features (pixels) vs the diabetes regression dataset having only 10 features.**The more data we're dealing with, the bigger the improvement we see in Rust**. We're even giving Python some leeway by warming up the runtime on the connection before the test, which typically takes a second or two to interpret all of PostgresML's dependencies. Since Rust is a compiled language, there is no longer a need to warmup the connection.
184+
The results are somewhat staggering. We didn't spend any time intentionally optimizing Rust over Python; most of the time was spent just trying to get things to compile. 😅. It's hard to believe the difference is this significant, but those fringe operations outside of the core machine learning algorithms really do dominate, requiring up to 35x more time in Python during inference. The difference between classification and regression here are related to the dataset size. The Scikit-Learn handwritten image classification dataset effectively has 64 features (pixels) vs. the diabetes regression dataset having only 10 features.
185+
186+
**The more data we're dealing with, the bigger the improvement we see in Rust**. We're even giving Python some leeway by warming up the runtime on the connection before the test, which typically takes a second or two to interpret all of PostgresML's dependencies. Since Rust is a compiled language, there is no longer such a requirement: all the code is warm and optimized.
183187

184188
<center>
185189
<iframe width="600" height="371" seamless frameborder="0" scrolling="no" src="https://docs.google.com/spreadsheets/d/e/2PACX-1vShmCVrYwmscys5TIo7c_C-1M3gE_GwENc4tTiU7A6_l3YamjJx7v5bZcafLIDcEIbFu-C2Buao4rQ6/pubchart?oid=345126465&amp;format=interactive"></iframe>
186190
</center>
187191

188192
>_This language comparison uses in-process data access. Python based machine learning microservices that communicate with other services over HTTP with JSON or gRPC interfaces will look even worse in comparison, especially if they are stateless and rely on yet another database to provide their data over yet another wire._
189193
190-
##Preservingbackward compatibility
194+
##PreservingAackward Compatibility
191195
```sql linenums="1" title="train.sql"
192196
SELECTpgml.train(
193197
project_name=>'Handwritten Digit Classifier',
@@ -203,10 +207,10 @@ SELECT pgml.predict('Handwritten Digit Classifier', image)
203207
FROMpgml.digits;
204208
```
205209

206-
The API is identical between versions1.0 and2.0. We take breaking changes seriously and we're not going to break existing deployments just because we're rewriting the whole project. The only reason we're bumping the major version is because we feel like this is a dramatic change, but we intend to preserve a full compatibility layer with models trained on1.0 in Python.This means that to get the full performance benefits, you'll need to retrain models after upgrading.
210+
The API is identical between versionsv1.0 andv2.0. We take breaking changes seriously and we're not going to break existing deployments just because we're rewriting the whole project. The only reason we're bumping the major version is because we feel like this is a dramatic change, but we intend to preserve a full compatibility layer with models trained onv1.0 in Python.However, this does mean that to get the full performance benefits, you'll need to retrain models after upgrading.
207211

208-
##Ensuringhigh quality Rustimplementations
209-
Besides backwards compatibility, we're building a Python compatibility layer to guarantee we can preserve the full Python model training APIs,when Rust APIs are not at parity in terms of functionality, quality or performance. We started this journey thinking that the olderalgorithms in scikit learn that are implementedinvanilla Pythonwould be the best candidates for replacement in Rust, but that is only partly true. There are high quality efforts in[linfa](https://github.com/rust-ml/linfa) and[smartcore](https://github.com/smartcorelib/smartcore) that also show 10-30x speedup overscikit, but they still lack some of the deeper functionality like joint regression, some of the more obscure algorithms andhyperparams, and some of the error handling that has been hardened intoscikit with mass adoption.
212+
##EnsuringHigh Quality RustImplementations
213+
Besides backwards compatibility, we're building a Python compatibility layer to guarantee we can preserve the full Python model training APIs,since Rust APIs are not at parity in terms of functionality, quality or performance. We started this journey thinking that the oldervanilla Python algorithmsinScikitwould be the best candidates for replacement in Rust, but that is only partly true. There are high quality efforts in[linfa](https://github.com/rust-ml/linfa) and[smartcore](https://github.com/smartcorelib/smartcore) that also show 10-30x speedup overScikit, but they still lack some of the deeper functionality like joint regression, some of the more obscure algorithms andhyperparameters, and some of the error handling that has been hardened intoScikit with mass adoption.
210214

211215
<center>
212216
<iframe width="600" height="371" seamless frameborder="0" scrolling="no" src="https://docs.google.com/spreadsheets/d/e/
@@ -225,11 +229,11 @@ The Rust implementations also produce high quality predictions against test sets
225229
<iframe width="600" height="371" seamless frameborder="0" scrolling="no" src="https://docs.google.com/spreadsheets/d/e/2PACX-1vShmCVrYwmscys5TIo7c_C-1M3gE_GwENc4tTiU7A6_l3YamjJx7v5bZcafLIDcEIbFu-C2Buao4rQ6/pubchart?oid=631927399&amp;format=interactive"></iframe>
226230
</center>
227231

228-
Interestingly, the training times for some of the simplest algorithms aremuchworse in the Rust implementation. Until we can guarantee eachalgorithm implementation is an upgrade in every way, we'll continue to use the Python compatibility layer on a case by case basis to avoid any unpleasant surprises.
232+
Interestingly, the training times for some of the simplest algorithms are worse in the Rust implementation. Until we can guarantee eachRust algorithm is an upgrade in every way, we'll continue to use the Python compatibility layer on a case by case basis to avoid any unpleasant surprises.
229233

230-
We believe that[machine learning in Rust](https://www.arewelearningyet.com/) is mature enough to add significant value now, where we'll be using the same underlying C libraries, andthatit's worth contributing to the Rustimplementations further to helpbringthem up to full feature parity.With this goal in mind, we intend to drop our Python compatibility layer completely in 3.0, and only support 2.0 models trained with Rust long term. Part of our 2.0releaseprocesswill include a benchmark suite for the full API we support via all Python libraries, so that we can track our progress toward pure Rust implementationsacross the board.
234+
We believe that[machine learning in Rust](https://www.arewelearningyet.com/) is mature enough to add significant value now. We'll be using the same underlying C/C++ libraries, and it's worth contributing to the RustML ecosystembringit up to full feature parity.Our v2.0release will include a benchmark suite for the full API we support via all Python libraries, so that we can track our progress toward pure Rust implementationsover time.
231235

232-
Many thanks and ❤️ to all those who are supporting this endeavor. We’d love to hear feedback from the broader ML and Engineering community about applications and other real world scenarios to help prioritize our work.We'd also appreciate your supportin the form of[starsonour github](https://github.com/postgresml/postgresml).
236+
Many thanks and ❤️ to all those who are supporting this endeavor. We’d love to hear feedback from the broader ML and Engineering community about applications and other real world scenarios to help prioritize our work.You can show your supportby[starring usonGitHub](https://github.com/postgresml/postgresml).
233237

234238
<center>
235239
<videocontrolsautoplayloopmutedwidth="90%"style="box-shadow:008px#000;">

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp