Hugging Face for Excel

🧪

EXPERIMENTAL: Breaking changes to the API are probable. Please provide feedback.

Inference models and spaces on Hugging Face from Excel functions. Free to use. Install from the Microsoft AppSource store at the link below, or directly from Excel.

AppSource

Overview

Provides Excel custom functions which wrap existing Hugging Face JavaScript libraries (specifically @huggingface/inference, @gradio/client, @xenova/transformers) so that you can inference models and spaces on Hugging Face without having to build/host/publish an Excel add-in.

We’re thinking this could be useful for the following types of users:

  • Data scientists that want an easy way to enable end-users to use their models from the familiar interface of Excel.
  • Excel wizards that want to build their own custom AI functions using existing models available on Hugging Face.
  • Model testers and labelers that need an easy way to run datasets through a model and annotate results.

As an example, you could build a custom function that translates text from one language to another using a Hugging Face model, similar to what we did in our Translate for Excel add-in, which uses Transformers.js and the Opus-MT series of models.

These functions are intended to be consumed in a named Excel LAMBDA function to conceal details not relevant to end-users (e.g. task, model, hf_token, endpoint, etc.).

Features

🆓 Unlimited free use.
🔒 None of your data is sent to our servers.
💻 Option to inference locally.
🚀 Fast way to test or operationalize your model.

Demo

Download a copy of the demo workbook to see the functions in action. You’ll need to put your hf_token on the ReadMe sheet to use the serverless API inference.

Functions

As outlined below, the Gradio function uses a repeating parameter function signature to enable it to pass an arbitrary data payload. All other functions are designed around Transformers pipeline tasks such as translation, summarization, etc. regardless of whether inferencing is local or via API (serverless or dedicated). We have initially supported a small subset of Transformers tasks, with the most common parameters for each.

Gradio

Gradio is a great way to build AI demos, and is increasingly being used to host APIs for production applications. Our HF.GRADIO function uses the Gradio JavaScript client under the hood to connect to the API of a Gradio space and provide user feedback on queue status, ETA, etc. The function signature is as follows:

=HF.GRADIO(hf_space, hf_token, arg1, arg2, ...)
ParameterRequiredDescription
hf_spaceYesGradio Space ID (e.g. “boardflare/translation”).
hf_tokenNoNeeded for private spaces (e.g. “hf_eiffw3..“).
arg1, arg2, …YesData array elements to be passed to the space.

e.g. =HF.GRADIO("boardflare/translation", "hf_eiffw3..", "Hello", "en", "fr") for a translation space demo we built with similar functionality to the HF.TRANSLATION function below.

The arg1, arg2, ... is a repeating parameter in Excel which means you can pass as many arguments as you like and they will be packaged as an array and sent to the space as a payload of shape {data: [arg1, arg2, ...]}. The args can be of any Excel scalar type (e.g. string, number, boolean). You need to ensure they are passed in the order they are expected by your Gradio app. The return from the Gradio app must be a scalar of one of the above types. In case you’re wondering if it is technically possible for each of the args and the return to be matrix values (i.e. an Excel range), the answer is yes. This is not supported currently because it means all arguments would be sent as a matrix, even if they are just single cells, e.g. {data: [[["foo"]], [["bar"]], ...]}, since there can be only one repeating parameter in the function. This doesn’t work with single-line standard Gradio app interfaces. The solution is to use Python code on both sides (Gradio and Excel) to shape the data as needed. More on this in the Architecture and Roadmap sections below.

Translation

The HF.TRANSLATION function signature is as follows:

=HF.TRANSLATION(hf_model, text, [src_lang], [tgt_lang], [hf_token], [hf_endpoint])

The parameters are as follows:

ParameterRequiredDescription
hf_modelYesmodel name (e.g. Helsinki-NLP/opus-mt-en-de).
textYesText to be translated.
src_langNoSource language code (e.g. “en”).
tgt_langNoTarget language code (e.g. “de”).
hf_tokenNoHF token (e.g. hf_ddie3kd…).
hf_endpointNoInference endpoint (e.g. “https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2”).

Output: the translated text string.

e.g. =HF.TRANSLATION("facebook/mbart-large-50-many-to-many-mmt", "Hello, how are you?", "en", "de") for translation from English to German using serverless API with no token.

e.g. =HF.TRANSLATION("Xenova/m2m100_418M", "Hello, how are you?", "en", "de") for translation from English to German using local inference.

If you are new to using translation on Hugging Face, here are some tips:

  • Single language-pair models such as Helsinki-NLP/opus-mt-en-de, do not need the src_lang and tgt_lang parameters, as the model has been trained to just handle that single pair.
  • Multi-lingual models such as facebook/mbart-large-50-many-to-many-mmt need the src_lang and tgt_lang parameters. However, the supported languages and formats are not always on the model card, and vary between models (e.g. en, en_XX, etc.). The translation pipeline with Transformers.js has good documentation on which parameters to use for common models. Note: there are also cases where models requiring src_lang and tgt_lang such as facebook/m2m100_418M have been incorrectly set up on the inference API to use the Text2Text Generation task, and so will throw an error when the parameters are passed.
  • Generalized text-to-text models such as T5 are trained to do translation and can be inferenced using the transformers pipeline with a task of translation_xx_to_yy, e.g. translation_en_to_fr, which will prepend the required prompt to your text, e.g. translate English to French: My name is Wolfgang and I live in Berlin. However, when using the inference API with a Text2Text model like T5, you need to prepend your own translation prompt for the desired language pair, e.g. translate English to French:..., because it is running a Text2Text Generation task. Note that T5 prompts are also in English, regardless of the languages.

Summarization

The HF.SUMMARIZATION function signature is as follows:

=HF.SUMMARIZATION(hf_model, text, [max_length], [hf_token], [hf_endpoint])

The parameters are as follows:

ParameterRequiredDescription
hf_modelYesModel name (e.g. facebook/bart-large-cnn).
textYesText to be summarized.
max_lengthNoMaximum length of the summary (tokens).
hf_tokenNoHF token (e.g. hf_ddie3kd…).
hf_endpointNoInference endpoint (e.g. “https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2”).

Output: the summarized text string.

e.g. =HF.SUMMARIZATION("facebook/bart-large-cnn", "The tower is 324 meters (1,063 ft) tall, about the same height as an 81-story building, and the tallest structure in Paris. Its base is square, measuring 125 meters (410 ft) on each side. During its construction, the Eiffel Tower surpassed the Washington Monument to become the tallest building in the world, a title it held for more than 40 years until the completion of the Chrysler Building in New York City in 1930.") for summarization using serverless API with no token.

Zero-shot Classification

The HF.ZERO_SHOT_CLASSIFICATION function signature is as follows:

=HF.ZERO_SHOT_CLASSIFICATION(hf_model, text, labels, [hf_token], [hf_endpoint])

The parameters are as follows:

ParameterRequiredDescription
hf_modelYesModel name (e.g. facebook/bart-large-mnli).
textYesText to classify.
labelsYesRange of labels to score (e.g. D2:D5)
hf_tokenNoHF token (e.g. hf_ddie3kd…).
hf_endpointNoInference endpoint (e.g. “https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2”).

Output: a range of scores for each label which will spill across columns.

e.g. =HF.ZERO_SHOT_CLASSIFICATION("facebook/bart-large-mnli", "I am feeling great today", D2:D5) for zero-shot classification using serverless API with no token, where D2:D5 contains the labels to score, e.g. “positive”, “negative”, “neutral”, “mixed”.

Text Generation

The HF.TEXT_GENERATION function signature is as follows:

=HF.TEXT_GENERATION(hf_model, text, [max_length], [hf_token], [hf_endpoint])

The parameters are as follows:

ParameterRequiredDescription
hf_modelYesModel name (e.g. Xenova/distilgpt2).
textYesText to generate from.
max_lengthNoMaximum length of the generated text (tokens).
hf_tokenNoHF token (e.g. hf_ddie3kd…).
hf_endpointNoInference endpoint (e.g. “https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2”).

Output: the generated text string.

e.g. =HF.TEXT_GENERATION("Xenova/distilgpt2", "Once upon a time") for text generation locally.

example.js
console.log('hello, world')

Architecture

Excel add-ins with custom functions are a web app with a functions.json file that defines the function signature in Excel and a functions.js file that runs when the function is called. A manifest.xml file is used to tell Excel where to find the above files, and the add-in name, icon, etc.

For example, a simple functions.json that performs sentiment analysis on a string might look like this:

functions.json
{
  "functions": [
    {
      "description": "Performs sentiment analysis on a string.",
      "id": "SENTIMENT_ANALYSIS",
      "name": "SENTIMENT_ANALYSIS",
      "parameters": [
        {
          "name": "text",
          "description": "The text to analyze.",
          "type": "string"
        }
      ]
    }
  ]
}

And the functions.js might look like this:

functions.js
// Define the SENTIMENT_ANALYSIS function
async function sentimentAnalysis(text) {
  const response = await fetch('https://api.example.com/sentiment', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ text: text })
  });
  const result = await response.json();
  return result.sentiment;
}
 
// Let Excel know sentimentAnalysis is the handler for the SENTIMENT_ANALYSIS function defined in functions.json
CustomFunctions.associate("SENTIMENT_ANALYSIS", sentimentAnalysis);

functions.js runs in a browser, either the WebView2 control in Excel for Windows (based on Chromium) or an iframe in Excel for the web. For local model inferencing, a web worker is used to run the Transformers.js library. Pyodide or PyScript could also be used to run Python code in the browser. The Anaconda Toolbox for Excel is an example of running Python code in Excel this way.

The built-in Python in Excel (soon to be GA) enables arbitrary Python code to be run in Excel using an Azure runtime, and the Anacode Code tool enables the same locally using the above mentioned PyScript. Both of these tools open up the option to run Python code to wrap a generic Excel custom function which calls Hugging Face APIs. This would be similar to what we’ve provided with the Gradio function, but with more flexibility and control over the data payload. Why not just call the Hugging Face APIs directly from Python? The Python in Excel runtime is sandboxed to not allow network access, similar to runtimes used by LLMs.

Since it is just a web app, you could host a custom Excel add-in on a Hugging Face static space, although a reverse proxy is needed to provide CORS support when used in Excel for the web. Taking the customization a step further, one could prompt an LLM to create an entirely custom Excel add-in and push the code to a static space.

There are over a billion Excel users worldwide, and many of them will be starting to dabble in Python with the coming GA of Python in Excel. This will be greatly accelerated by LLMs (e.g. Copilot in Excel) enabling them to write Python code in Excel without really needing to know Python. Our feeling is that this will open the door to many more Excel wizards becoming DIY data scientists and wanting to use Hugging Face tools and models from Excel, and hopefully this add-in will help them get there faster.

Roadmap

This is an initial version to gather feedback. Some ideas for future enhancements:

  • Support for more transformers tasks, in particular chat completion prompts.
  • Upgrade to v3 Transformers.js and WebGPU support for faster local inference.
  • AutoTrain API support to fine-tune a model directly from Excel.
  • Deploy add-in to a HF static space so people can easily duplicate it and customize it to their needs.
  • Add user authentication and centralized hf_token management for enterprises so tokens are not hard-coded in Excel workbooks, and IT / model developers can gather user-level metrics for endpoint consumption.
  • Generic Gradio and Transformer functions which accept an artibrary number of range inputs, and return a range output. Basically this would be one function to rule them all, using a Python in Excel wrapper to handle the data transformation, but eliminating the need to build/host/publish an Excel add-in.

If any of these things are of keen interest to you, please let us know.