How To Call Cohere and Hugging Face AI from within an Oracle database using JavaScript (store and access results using SQL, JSON, and REST)

June 27, 2023 | 10 minute read
Paul Parkinson
Architect and Developer Evangelist, Microservices and Converged Database
Text Size 100%:

In this blog, I will show you how to quickly create an entirely free app using a JavaScript program that runs within the free Oracle database and calls Hugging Face AI, the results of which are stored in the database and can then be accessed using SQL, JSON, Rest, or any other language.  All of the source is of course available here.

hugging face access from Oracle database using JavaScript

 

A common flow of applications in general and AI applications specifically involves an app calling an AI service and then storing the information in the database where it may be retrieved and processed (eg, using OML) further and/or analyzed and queried later.

By issuing the command from the database itself the data is stored immediately and is thus also more reliable as it is in-process and does not require an extra network call to persist.   Further, by having the logic (and even code) reside in the database, the high availability, management, observability, etc. of the power Oracle database can be implicitly, inherently leveraged. 

This is a unique capability of the Oracle database as it includes Java, and, as we'll see in this blog, JavaScript runtime engines within the database itself. 

Hugging Face develops tools for building applications using machine learning. It is most notable for its transformers library built for natural language processing applications and its platform that allows users to share machine learning models and datasets.  It has become extremely popular over the last couple of years.

In short, we'll...

  1. Create a cohere.com or huggingface.co account, create and copy an access token, and select a model.
  2. Create the Oracle database.
  3. Create the database user and table(s).
  4. Run a short JavaScript program in the database to make a call to the Cohere or Hugging Face AI model and store the results in the table. 
  5. Query these results using SQL, JSON, Rest, etc.

 

Setup Cohere account and AI model

Go to https://cohere.com and Sign Up, go to your Profile, and click the Settings button.

Click on Dashboard, then API Keys, create a key (or use trial), and copy its value for use later.

Cohere API keys

Click on API Reference and select hamburger menu/icon on the left of any page to view API Reference list and select one. In this case, we will select generate section and Co.Generate

Coherence API keys

Select Ianguage and then select the JavaScript option in order to see a sample code snippet to call the model.

Coherence code example

 

Setup Hugging Face account and AI model

Go to https://huggingface.co and Sign Up, go to your Profile, and click the Settings button.

Click on Access Tokens, create a token, and copy its value for use later.

create huggingface account and token

 

Click on Models and select a model. In this case, we will select a model under the Natural Language Processing section for Question Answering

select hugging face model

 

Select a model (perhaps one of the more popular ones), notice the information in the Model Card on the left, and then select the Deploy drop-down menu on the right.

select huggingface api JS source

 

Select Inference API and then select the JavaScript option in order to see a sample code snippet to call the model.

observe JS huggingface code snippet

 

Setup Oracle  Database

We can use any flavor of the Oracle database 23c.  On the cloud, we can use Oracle always free autonomous database later this year when 23c should be available. We can use the Oracle 23c Free version as it's available now and we can simply install or use a container image locally. Or of course, we could use the local for dev and cloud for production, etc. and either of these options is very quick to set up...

 

Oracle Database Free... 

You can go here to set up the Oracle Database Free 23c

Using the container image is very simple. You can simply pull the image:

docker pull container-registry.oracle.com/database/free:latest

and then execute the one line below, replacing -e ORACLE_PASSWORD=Welcome12345 with a password of your choice (you can also add a -v oracle-volume:/somedirectory parameter with a directory location in order to persist changes across restarts). Notice the --add-host docker.for.mac.host.internal:host-gateway param that allows calls out of the container. This is the setting for macs and will be different if running on a different OS.

docker run -d -p 1521:1521 --add-host docker.for.mac.host.internal:host-gateway -e ORACLE_PASSWORD=Welcome12345 gvenzl/oracle-free

Setup SQLcl (or Database Actions) and connect

You can install SQLcl to manage the database by

  • Downloading and install from this location https://www.oracle.com/database/sqldeveloper/technologies/sqlcl/download/ This will provide an [SQLcl_INSTALL_DIR]/bin/sql executable that we will use to administer the database. For convenience, you may add [SQLcl_INSTALL_DIR]/bin to your PATH.
  • Login replacing [SQLcl_INSTALL_DIR] with the location of your SQLcl and replacing Welcome12345 with the one you provided as ORACLE_PASSWORD when creating the database Here is an example when using a local install (eg Oracle Database Free container image):

    [SQLcl_INSTALL_DIR]/bin/sql /nolog SQL> connect sys@//localhost:1521/freepdb1 as sysdba Password? (**********?) ************* Connected.

 

Create the users, with appropriate priviledges, that will call Cohere and/or Hugging Face via JavaScript.
 

Run the following SQL files to create the aijs user and its necessary grants and ACLs (note that these can be further tightened for better security). 

SQL> @sql/create_aijs_user.sql

SQL> @sql/create_aijs_acl.sql

Now connect the user and create a table to store the results of the call to Hugging Face

SQL> connect aijs/Welcome12345;

SQL> create table huggingfacejson (id json);

SQL> create table coherejson (id json);

Now everything is ready to run!

Run either the Cohere or HuggingFace queries from the JavaScript code in the database

Cohere Example

SQL> @sql/coherequery.sql

L/SQL procedure successfully completed.

Then, check the JSON results stored in the table by doing a SQL query.

SQL> select * from coherejson;

[{"id":"1b42f8f9-ea6d-4a65-8f02-bdcf89d9bd79","generations":[{"id":"d6467c0b-4a78-4dd4-b822-c1e2bfa4ecb0","text":"\n LLMs or Large Language Models are artificial intelligence tools that can read, summarize and translate texts and"}],"prompt":"Please explain to me how LLMs work","meta":{"api_version":{"version":"1"}}}    

 

Looking at the code we just executed we can see the JavaScript module created and the function being called:

create or replace mle module cohere_module
language javascript as

import "mle-js-fetch";
import "mle-js-oracledb";

export async function cohereDemo(apiToken) {

    if (apiToken === undefined) {
        throw Error("must provide an API token");
    }

    const modelId = "generate";
    const restAPI = `https://api.cohere.ai/v1/${modelId}`;

    const headers = {
                         accept: 'application/json',
                         'content-type': 'application/json',
                         "Authorization": `Bearer ${apiToken}`
                       };

    const payload = {
     max_tokens: 20,
     return_likelihoods: 'NONE',
     truncate: 'END',
     prompt: 'Please explain to me how LLMs work'
    };

    const resp = await fetch(
        restAPI, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload),
            credentials: "include"
        }
    );
    const resp_json = await resp.json();

    session.execute(
        `INSERT INTO COHEREJSON (id) VALUES (:resp_json)`,
           [ JSON.stringify(resp_json) ]
    );

}
/

create or replace procedure coherequery(
    p_API_token varchar2
) as mle module cohere_module
signature 'cohereDemo(string)';
/

-- this is how you can test the API call
begin
    utl_http.set_wallet('system:');
    coherequery('[yourcoheretokenhere]');
end;
/

 

Hugging Face Example

SQL> @sql/huggingfacequery.sql PL/SQL procedure successfully completed.

Then, check the JSON results stored in the table by doing a SQL query.
 

SQL> select * from huggingfacejson; [{"score":0.16964051127433777,"token":2053,"token_str":"no","sequence":"the answer to the universe is no."},{"score":0.07344779372215271,"token":2498,"token_str":"nothing","sequence":"the answer to the universe is nothing."},{"score":0.05803246051073074,"token":2748,"token_str":"yes","sequence":"the answer to the universe is yes."},{"score":0.043957971036434174,"token":4242,"token_str":"unknown","sequence":"the answer to the universe is unknown."},{"score":0.04015727713704109,"token":3722,"token_str":"simple","sequence":"the answer to the universe is simple."}]    

 

Looking at the code we just executed we can see the JavaScript module created and the function being called:

create or replace mle module huggingface_module
language javascript as

import "mle-js-fetch";
import "mle-js-oracledb";

export async function huggingfaceDemo(apiToken) {

    if (apiToken === undefined) {
        throw Error("must provide an API token");
    }

    const payload = {
        inputs: "The answer to the universe is [MASK]."
    };
    const modelId = "bert-base-uncased";

    const headers = {
        "Authorization": `Bearer ${apiToken}`
    };

    const restAPI = `https://api-inference.huggingface.co/models/${modelId}`;

    const resp = await fetch(
        restAPI, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload),
            credentials: "include"
        }
    );

    const resp_json = await resp.json();

    session.execute(
        `INSERT INTO HUGGINGFACEJSON (id) VALUES (:resp_json)`,
        [ JSON.stringify(resp_json) ]
    );
}
/

create or replace procedure huggingfacequery(
    p_API_token varchar2
) as mle module huggingface_module
signature 'huggingfaceDemo(string)';
/

-- this is how you can test the API call
begin
    utl_http.set_wallet('system:');
    huggingfacequery('[hf_yourhuggingfacetokenhere]');
end;
/

Useful parameters and debug information for Hugging Face can be found here.
 

The results can now be queried, analyzed, etc. using SQL or JSON (simultanious thanks to the new JSON duality feature), REST or even the MongoDB API.

Oracle Database is the perfect database for AI for a number of reasons, particularly as it is a vector database with capabilities such as the following already available today:

  • Native data types for vector representation and storage: RAW, BLOB, JSON
  • In-Memory Column Store to store & search vector embeddings w/ SIMD kernels for amazing performance
  • Extensible indexing framework to create data-model specific indices (e.g., Text, Spatial)
  • Native Oracle Machine Learning APIs - Modeling, Classification, Scoring, Clustering, etc.
  • Plus, many other capabilities which, used together, make Oracle a better Vector Database
  • DMLs, Parallel Loading, Partitioning, Advanced Compression, Parallel Query, RAC, Sharding, etc.

It is also possible to call Oracle OCI AI and other services from within the Oracle database.

Conclusion

The blog went into how to call Hugging Face APIs from within the Oracle database using JavaScript thus demonstrating a powerful combination of features perfectly suited to a broad array of AI solutions and friendly to JavaScript developers.

Some other blogs related to JavaScript in the database, in general, the MultiLingual Engine (MLE) that makes it possible, etc. can be found in Martin Bach's blogs and this post about JavaScript modules. Thanks to Martin and Lucas for all their help.

I look forward to any comments or questions you may have and really appreciate your time reading.

Paul Parkinson

Architect and Developer Evangelist, Microservices and Converged Database

Paul is Architect and Developer Evangelist for Microservices and the Converged Database

His focus includes data and transaction processing, service mesh and event mesh, observability, and polyglot data models, languages, and frameworks.

The 18 years prior to this he was the Transaction Processing Dev Lead for the Mid-tier and Microservices (including WebLogic and Helidon)

Creator of the workshop "Building Microservices with Oracle Converged Database" @ http://bit.ly/simplifymicroservices

Holds 20+ patents and has given numerous presentations and publications over the past 20+ years.


Previous Post

Develop A Geocaching Multiplayer Game Using Flutter, Spring Boot, Oracle Database Free Spatial, and OpenStreetMap

Paul Parkinson | 11 min read

Next Post


Linting MLE JavaScript Modules in Continuous Integration Pipelines

Martin Bach | 20 min read