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.
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...
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.
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
Select Ianguage and then select the JavaScript option in order to see a sample code snippet to call the model.
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.
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 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 Inference API and then select the JavaScript option in order to see a sample code snippet to call the model.
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
[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.[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:
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 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
Next Post