Skip to main content

Python binding to Omikuji, an efficient implementation of Partioned Label Trees and its variations for extreme multi-label classification

Project description

Omikuji

Build Status Crate version PyPI version

An efficient implementation of Partitioned Label Trees (Prabhu et al., 2018) and its variations for extreme multi-label classification, written in Rust🦀 with love💖.

Features & Performance

Omikuji has has been tested on datasets from the Extreme Classification Repository. All tests below are run on a quad-core Intel® Core™ i7-6700 CPU, and we allowed as many cores to be utilized as possible. We measured training time, and calculated precisions at 1, 3, and 5. (Note that, due to randomness, results might vary from run to run, especially for smaller datasets.)

Parabel, better parallelized

Omikuji provides a more parallelized implementation of Parabel (Prabhu et al., 2018) that trains faster when more CPU cores are available. Compared to the original implementation written in C++, which can only utilize the same number of CPU cores as the number of trees (3 by default), Omikuji maintains the same level of precision but trains 1.3x to 1.7x faster on our quad-core machine. Further speed-up is possible if more CPU cores are available.

Dataset Metric Parabel Omikuji
(balanced,
cluster.k=2)
EURLex-4K P@1 82.2 82.1
P@3 68.8 68.8
P@5 57.6 57.7
Train Time 18s 14s
Amazon-670K P@1 44.9 44.8
P@3 39.8 39.8
P@5 36.0 36.0
Train Time 404s 234s
WikiLSHTC-325K P@1 65.0 64.8
P@3 43.2 43.1
P@5 32.0 32.1
Train Time 959s 659s

Regular k-means for shallow trees

Following Bonsai (Khandagale et al., 2019), Omikuji supports using regular k-means instead of balanced 2-means clustering for tree construction, which results in wider, shallower and unbalanced trees that train slower but have better precision. Comparing to the original Bonsai implementation, Omikuji also achieves the same precisions while training 2.6x to 4.6x faster on our quad-core machine. (Similarly, further speed-up is possible if more CPU cores are available.)

Dataset Metric Bonsai Omikuji
(unbalanced,
cluster.k=100,
max_depth=3)
EURLex-4K P@1 82.8 83.0
P@3 69.4 69.5
P@5 58.1 58.3
Train Time 87s 19s
Amazon-670K P@1 45.5* 45.6
P@3 40.3* 40.4
P@5 36.5* 36.6
Train Time 5,759s 1,753s
WikiLSHTC-325K P@1 66.6* 66.6
P@3 44.5* 44.4
P@5 33.0* 33.0
Train Time 11,156s 4,259s

*Precision numbers as reported in the paper; our machine doesn't have enough memory to run the full prediction with their implementation.

Balanced k-means for balanced shallow trees

Sometimes it's desirable to have shallow and wide trees that are also balanced, in which case Omikuji supports the balanced k-means algorithm used by HOMER (Tsoumakas et al., 2008) for clustering as well.

Dataset Metric Omikuji
(balanced,
cluster.k=100)
EURLex-4K P@1 82.1
P@3 69.4
P@5 58.1
Train Time 19s
Amazon-670K P@1 45.4
P@3 40.3
P@5 36.5
Train Time 1,153s
WikiLSHTC-325K P@1 65.6
P@3 43.6
P@5 32.5
Train Time 3,028s

Layer collapsing for balanced shallow trees

An alternative way for building balanced, shallow and wide trees is to collapse adjacent layers, similar to the tree compression step used in AttentionXML (You et al., 2019): intermediate layers are removed, and their children replace them as the children of their parents. For example, with balanced 2-means clustering, if we collapse 5 layers after each layer, we can increase the tree arity from 2 to 2⁵⁺¹ = 64.

Dataset Metric Omikuji
(balanced,
cluster.k=2,
collapse 5 layers)
EURLex-4K P@1 82.4
P@3 69.3
P@5 58.0
Train Time 16s
Amazon-670K P@1 45.3
P@3 40.2
P@5 36.4
Train Time 460s
WikiLSHTC-325K P@1 64.9
P@3 43.3
P@5 32.3
Train Time 1,649s

Build & Install

Omikuji can be easily built & installed with Cargo as a CLI app:

cargo install omikuji --features cli

Or install from the latest source:

cargo install --git https://github.com/tomtung/omikuji.git --features cli

The CLI app will be available as omikuji. For example, to reproduce the results on the EURLex-4K dataset:

omikuji train eurlex_train.txt --model_path ./model
omikuji test ./model eurlex_test.txt --out_path predictions.txt

Python Binding

A simple Python binding is also available for training and prediction. It can be install via pip:

pip install omikuji

Note that you might still need to install Cargo should compilation become necessary.

You can also install from the latest source:

pip install git+https://github.com/tomtung/omikuji.git -v

The following script demonstrates how to use the Python binding to train a model and make predictions:

import omikuji

# Train
hyper_param = omikuji.Model.default_hyper_param()
# Adjust hyper-parameters as needed
hyper_param.n_trees = 5
model = omikuji.Model.train_on_data("./eurlex_train.txt", hyper_param)

# Serialize & de-serialize
model.save("./model")
model = omikuji.Model.load("./model")
# Optionally densify model weights to trade off between prediction speed and memory usage
model.densify_weights(0.05)

# Predict
feature_value_pairs = [
    (0, 0.101468),
    (1, 0.554374),
    (2, 0.235760),
    (3, 0.065255),
    (8, 0.152305),
    (10, 0.155051),
    # ...
]
label_score_pairs =  model.predict(feature_value_pairs)

Usage

$ omikuji train --help
omikuji-train
Train a new model

USAGE:
    omikuji train [FLAGS] [OPTIONS] <TRAINING_DATA_PATH>

FLAGS:
        --cluster.unbalanced     Perform regular k-means clustering instead of balanced k-means clustering
    -h, --help                   Prints help information
        --train_trees_1_by_1     Finish training each tree before start training the next; limits initial
                                 parallelization but saves memory
        --tree_structure_only    Build the trees without training classifiers; useful when a downstream user needs the
                                 tree structures only
    -V, --version                Prints version information

OPTIONS:
        --centroid_threshold <THRESHOLD>         Threshold for pruning label centroid vectors [default: 0]
        --cluster.eps <EPS>                      Epsilon value for determining clustering convergence [default: 0.0001]
        --cluster.k <K>                          Number of clusters [default: 2]
        --cluster.min_size <SIZE>
            Labels in clusters with sizes smaller than this threshold are reassigned to other clusters instead [default:
            2]
        --collapse_every_n_layers <N>
            Number of adjacent layers to collapse, which increases tree arity and decreases tree depth [default: 0]

        --linear.c <C>                           Cost co-efficient for regularizing linear classifiers [default: 1]
        --linear.eps <EPS>
            Epsilon value for determining linear classifier convergence [default: 0.1]

        --linear.loss <LOSS>
            Loss function used by linear classifiers [default: hinge]  [possible values: hinge, log]

        --linear.max_iter <M>
            Max number of iterations for training each linear classifier [default: 20]

        --linear.weight_threshold <THRESHOLD>
            Threshold for pruning weight vectors of linear classifiers [default: 0.1]

        --max_depth <DEPTH>                      Maximum tree depth [default: 20]
        --min_branch_size <SIZE>
            Number of labels below which no further clustering & branching is done [default: 100]

        --model_path <PATH>
            Optional path of the directory where the trained model will be saved if provided; if an model with
            compatible settings is already saved in the given directory, the newly trained trees will be added to the
            existing model
        --n_threads <T>
            Number of worker threads. If 0, the number is selected automatically [default: 0]

        --n_trees <N>                            Number of trees [default: 3]

ARGS:
    <TRAINING_DATA_PATH>    Path to training dataset file (in the format of the Extreme Classification Repository)
$ omikuji test --help
omikuji-test
Test an existing model

USAGE:
    omikuji test [OPTIONS] <MODEL_PATH> <TEST_DATA_PATH>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
        --beam_size <beam_size>           Beam size for beam search [default: 10]
        --k_top <K>                       Number of top predictions to write out for each test example [default: 5]
        --max_sparse_density <DENSITY>    Density threshold above which sparse weight vectors are converted to dense
                                          format. Lower values speed up prediction at the cost of more memory usage
                                          [default: 0.1]
        --n_threads <T>                   Number of worker threads. If 0, the number is selected automatically [default:
                                          0]
        --out_path <PATH>                 Path to the which predictions will be written, if provided

ARGS:
    <MODEL_PATH>        Path of the directory where the trained model is saved
    <TEST_DATA_PATH>    Path to test dataset file (in the format of the Extreme Classification Repository)

Data format

Our implementation takes dataset files formatted as those provided in the Extreme Classification Repository. A data file starts with a header line with three space-separated integers: total number of examples, number of features, and number of labels. Following the header line, there is one line per each example, starting with comma-separated labels, followed by space-separated feature:value pairs:

label1,label2,...labelk ft1:ft1_val ft2:ft2_val ft3:ft3_val .. ftd:ftd_val

Trivia

The project name comes from o-mikuji (御神籤), which are predictions about one's future written on strips of paper (labels?) at jinjas and temples in Japan, often tied to branches of pine trees after they are read.

References

  • Y. Prabhu, A. Kag, S. Harsola, R. Agrawal, and M. Varma, “Parabel: Partitioned Label Trees for Extreme Classification with Application to Dynamic Search Advertising,” in Proceedings of the 2018 World Wide Web Conference, 2018, pp. 993–1002.
  • S. Khandagale, H. Xiao, and R. Babbar, “Bonsai - Diverse and Shallow Trees for Extreme Multi-label Classification,” Apr. 2019.
  • G. Tsoumakas, I. Katakis, and I. Vlahavas, “Effective and efficient multilabel classification in domains with large number of labels,” ECML, 2008.
  • R. You, S. Dai, Z. Zhang, H. Mamitsuka, and S. Zhu, “AttentionXML: Extreme Multi-Label Text Classification with Multi-Label Attention Based Recurrent Neural Networks,” Jun. 2019.

License

Omikuji is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

omikuji-0.4.1.tar.gz (49.9 kB view details)

Uploaded Source

Built Distributions

omikuji-0.4.1-cp39-cp39-win_amd64.whl (362.5 kB view details)

Uploaded CPython 3.9 Windows x86-64

omikuji-0.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (824.0 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

omikuji-0.4.1-cp39-cp39-macosx_10_15_x86_64.whl (471.3 kB view details)

Uploaded CPython 3.9 macOS 10.15+ x86-64

omikuji-0.4.1-cp38-cp38-win_amd64.whl (362.5 kB view details)

Uploaded CPython 3.8 Windows x86-64

omikuji-0.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (824.0 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

omikuji-0.4.1-cp38-cp38-macosx_10_15_x86_64.whl (471.3 kB view details)

Uploaded CPython 3.8 macOS 10.15+ x86-64

omikuji-0.4.1-cp37-cp37m-win_amd64.whl (362.5 kB view details)

Uploaded CPython 3.7m Windows x86-64

omikuji-0.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (824.0 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

omikuji-0.4.1-cp37-cp37m-macosx_10_15_x86_64.whl (471.3 kB view details)

Uploaded CPython 3.7m macOS 10.15+ x86-64

omikuji-0.4.1-cp36-cp36m-win_amd64.whl (362.5 kB view details)

Uploaded CPython 3.6m Windows x86-64

omikuji-0.4.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (824.0 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.12+ x86-64 manylinux: glibc 2.5+ x86-64

omikuji-0.4.1-cp36-cp36m-macosx_10_15_x86_64.whl (471.3 kB view details)

Uploaded CPython 3.6m macOS 10.15+ x86-64

File details

Details for the file omikuji-0.4.1.tar.gz.

File metadata

  • Download URL: omikuji-0.4.1.tar.gz
  • Upload date:
  • Size: 49.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1.tar.gz
Algorithm Hash digest
SHA256 acf9316b7c2375568e95817d564f05e91e22b2f34dcb3af5bd75c5482e62c55b
MD5 ae529285b83a7e1029c5648dbbb31f94
BLAKE2b-256 89726dd843b1c39808a12e0ab0578ec23db31fbc5557fdce536a93d20a51afef

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 362.5 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 4b14426560dd11f6f180336486d1497f1be342cdecab1f2cb19a115625fe94c5
MD5 af7139c473ea3583c011293cc2fa380a
BLAKE2b-256 ca90205eb1e1797d7e417f1c338a14dd9e51653797ddf5ea779ff6d42f06af67

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for omikuji-0.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 e9afb7e60149effe82ead1425c4626ab14278a02d6e53406b488419d820c0ce2
MD5 12de793b411e420d7d99eecd16745e9e
BLAKE2b-256 c61b339b5237ff34b5c9df1f7982103698b0dba001a156d52a59e80b6253565e

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp39-cp39-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp39-cp39-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 471.3 kB
  • Tags: CPython 3.9, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp39-cp39-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 b66e6a02a017b2013f16446c99dd2c509fa2b4d2887580629fc49346db2ca011
MD5 fc4507faeed499b503700d9aed933046
BLAKE2b-256 0df6b42740ce1a09e1b9c22531f6ce85ddfdfe9f68d5da64a4bf0cd3f4600246

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 362.5 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 8db58c4ebac90fa6d49c18803013bceefcc2db84d656d35dad2ce2c02a29d080
MD5 8d08a15b38cfa4d6cd343dffd3eafb32
BLAKE2b-256 c22c27fd6a94485ca1841c104ef0378613261529ad2d41a7fe1b56ffb3003549

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for omikuji-0.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 c7c85468d6a2a4dfa113d971c3bfc8f0c22fed3181749806e3d24d2f5efd1e06
MD5 8eba01038971285e9893325eae266573
BLAKE2b-256 c572809b2cc78ba4f127cc9df4c5d8212cb45933f10bb3fe1bf8dc81264ce74c

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp38-cp38-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp38-cp38-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 471.3 kB
  • Tags: CPython 3.8, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp38-cp38-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 c6983bdc9223a4e404f2e8b1a43d702e070d83cb8fc938da86fdd39cee8861c1
MD5 61574e2758567ecee00dead702f2a8ec
BLAKE2b-256 85f8245590d8dbe9b9bac5bf205a9f67b97c0bbb63ee9475612fc9be6a63807e

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 362.5 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 807104d1ae4b617a3f7ded6900cf17665ace952fdd361fad8a6969dd455f7813
MD5 e1171233cd026b98e2ff4e6d0141558e
BLAKE2b-256 9196754e5bc241132c253b7199cb87292fdd1e9e0fea39ac133cef7681faa920

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for omikuji-0.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 069444248e56a9e56a47c61562f8f51a52a40f4343c009d17049b4b92fdef22a
MD5 739abcc3b96a52b9d47fef8c7d8b2d4d
BLAKE2b-256 14ea2123a310c66ecdf7cf625591d955d375a75fcc8267ded9141fa535e4ec9f

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp37-cp37m-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp37-cp37m-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 471.3 kB
  • Tags: CPython 3.7m, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp37-cp37m-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 cb91052c01b7231128f4cb3da1950bdc9f5bbeeb3302b558c6f735c4d44dcb17
MD5 201c4cb1cdb146755a722ae15450ecd0
BLAKE2b-256 7017b97346aa9b2ad6eab5a6e61c81f47715ce29ec5dcdae56d4d9357983c7db

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp36-cp36m-win_amd64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 362.5 kB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 ec1466befbc852faacf7d15b513a601d6e4a6a0a87c8fd2aeef53ef3bce8cc7a
MD5 5e798a3966b9e9e7de4bffcac8a715ed
BLAKE2b-256 38c34a6d2e94fd3c672c9f25418aa936468385b1847392c61187328511d0ec20

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl.

File metadata

File hashes

Hashes for omikuji-0.4.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 40b56edfcbff58f3eb72255e26f8a8430a2df9087962c31c7206676a35942f25
MD5 4eefbd099e174b47a3123e157c6264da
BLAKE2b-256 95c9d5fc2ff054b21a4b4dae0e4d3e13d55ae441d42692a88876458d462576d3

See more details on using hashes here.

File details

Details for the file omikuji-0.4.1-cp36-cp36m-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: omikuji-0.4.1-cp36-cp36m-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 471.3 kB
  • Tags: CPython 3.6m, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.8.2 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for omikuji-0.4.1-cp36-cp36m-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 0082df755a2a531fc64ab3e85883d793d57423c93bacf611fce86c4396034443
MD5 2996ed8c6ac7f0607875c880b1b2f007
BLAKE2b-256 150a90e1b439d1a710df05fad4c82fa03ab96897da9f8cd93bafceaefdaeb8ea

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page