Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Stillerman committed May 8, 2023
2 parents 9027e8b + a11b9c8 commit f78dbbe
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 41 deletions.
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
# Project for testing open source code completion models

It was forked from [tabnine-vscode](https://github.com/codota/tabnine-vscode) & modified for making it compatible with open sorurce code models on hf.co/models
It was forked from [tabnine-vscode](https://github.com/codota/tabnine-vscode) & modified for making it compatible with open source code models on [hf.co/models](https://huggingface.co/models)

## Installing

Install just like any other [vscode extension](https://marketplace.visualstudio.com/items?itemName=HuggingFace.huggingface-vscode).

By default, this extension is using [bigcode/starcoder](https://huggingface.co/bigcode/starcoder) & [Hugging Face Inference API](https://huggingface.co/inference-api) for the inference. However, you can [configure](#configuring) to make inference requests to your custom endpoint that is not Hugging Face Inference API. Thus, if you are using the default Hugging Face Inference AP inference, you'd need to provide [HF API Token](#hf-api-token).

#### HF API token

You can supply your HF API token ([hf.co/settings/token](https://hf.co/settings/token)) with this command:
1. `Cmd/Ctrl+Shift+P` to open VSCode command palette
2. Type: `Hugging Face Code: Set API token`

<img src="https://github.com/huggingface/huggingface-vscode/raw/master/assets/set-api-token.png" width="800px">

## Testing

1. Create a new python file
2. Try typing `def main():`

<img src="https://github.com/huggingface/huggingface-vscode/raw/master/assets/ext-working.png" width="800px">

#### Checking if the generated code in in [The Stack](https://huggingface.co/datasets/bigcode/the-stack)

Hit `Ctrl+Esc` to check if the generated code is in in [The Stack](https://huggingface.co/datasets/bigcode/the-stack).
This is a rapid first-pass attribution check using [stack.dataportraits.org](https://stack.dataportraits.org).
We check for sequences of at least 50 characters that match a Bloom filter.
This means false positives are possible and long enough surrounding context is necesssary (see the [paper](https://dataportraits.org/) for details on n-gram striding and sequence length).
[The dedicated Stack search tool](https://hf.co/spaces/bigcode/search) is a full dataset index and can be used for a complete second pass.


## Developing
Make sure you've [installed yarn](https://yarnpkg.com/getting-started/install) on your system.
1. Clone this repo: `git clone https://github.com/huggingface/huggingface-vscode`
Expand All @@ -34,12 +53,6 @@ You can configure: endpoint to where request will be sent and special tokens.

<img src="https://github.com/huggingface/huggingface-vscode/raw/master/assets/set-configs.png" width="800px">

#### HF API token

You can supply your HF API token (hf.co/settings/token) with this command:

<img src="https://github.com/huggingface/huggingface-vscode/raw/master/assets/set-api-token.png" width="800px">

Example:

Let's say your current code is this:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"publisher": "HuggingFace",
"name": "huggingface-vscode",
"version": "0.0.12",
"version": "0.0.24",
"displayName": "HF Code Autocomplete",
"description": "AI Autocomplete for OSS code-gen models",
"icon": "small_logo.png",
Expand Down
2 changes: 1 addition & 1 deletion src/globals/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const STATUS_NAME = "Tabnine";

export const INSTRUMENTATION_KEY = "<INSTRUMENTATION_KEY>";

export const CHAR_LIMIT = 100_000;
export const CHAR_LIMIT = 4_000;
export const MAX_NUM_RESULTS = 5;
export const CONSECUTIVE_RESTART_THRESHOLD = 100;
export const REQUEST_FAILURES_THRESHOLD = 20;
Expand Down
7 changes: 4 additions & 3 deletions src/inlineSuggestions/highlightStackAttributions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ export default async function highlightStackAttributions(): Promise<void> {
headers: { "Content-Type": "application/json" },
});

if(!resp.ok){
return;
}
if(!resp.ok){
return;
}

const json = await resp.json() as any as {spans: [number, number][]}
const {spans} = json

Expand Down
57 changes: 28 additions & 29 deletions src/runCompletion.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Position, Range, TextDocument, WorkspaceConfiguration, workspace } from "vscode";
import { Position, Range, TextDocument, WorkspaceConfiguration, workspace, window, env, Uri } from "vscode";
import {URL} from "url";
import fetch from "node-fetch";
import { AutocompleteResult, ResultEntry } from "./binary/requests/requests";
Expand All @@ -10,6 +10,8 @@ import { getTabnineExtensionContext } from "./globals/tabnineExtensionContext";

export type CompletionType = "normal" | "snippet";

let didShowTokenWarning = false;

export default async function runCompletion(
document: TextDocument,
position: Position,
Expand All @@ -19,23 +21,11 @@ export default async function runCompletion(
setLoadingStatus(FULL_BRAND_REPRESENTATION);
const offset = document.offsetAt(position);
const beforeStartOffset = Math.max(0, offset - CHAR_LIMIT);
const afterEndOffset = offset + CHAR_LIMIT;
// const afterEndOffset = offset + CHAR_LIMIT;
const beforeStart = document.positionAt(beforeStartOffset);
const afterEnd = document.positionAt(afterEndOffset);
// const afterEnd = document.positionAt(afterEndOffset);
const prefix = document.getText(new Range(beforeStart, position)) + currentSuggestionText;
const suffix = document.getText(new Range(position, afterEnd));
// const requestData = {
// filename: getFileNameWithExtension(document),
// prefix,
// suffix,
// region_includes_beginning: beforeStartOffset === 0,
// region_includes_end: document.offsetAt(afterEnd) !== afterEndOffset,
// max_num_results: getMaxResults(),
// offset,
// line: position.line,
// character: position.character,
// indentation_size: getTabSize(),
// };
// const suffix = document.getText(new Range(position, afterEnd));

type Config = WorkspaceConfiguration & {
modelIdOrEndpoint: string;
Expand All @@ -47,26 +37,37 @@ export default async function runCompletion(
temperature: number;
};
const config: Config = workspace.getConfiguration("HuggingFaceCode") as Config;
const { modelIdOrEndpoint, isFillMode, startToken, middleToken, endToken, stopToken, temperature } = config;
const { modelIdOrEndpoint, stopToken, temperature } = config;

const context = getTabnineExtensionContext();
const apiToken = await context?.secrets.get("apiToken");

let endpoint = ""
try{
new URL(modelIdOrEndpoint);
endpoint = modelIdOrEndpoint;
}catch(e){
endpoint = `https://api-inference.huggingface.co/models/${modelIdOrEndpoint}`
}

let inputs = `${startToken}${prefix}`;
if(isFillMode){
inputs += `${middleToken}${suffix}`;
// if user hasn't supplied API Token yet, ask user to supply one
if(!apiToken && !didShowTokenWarning){
didShowTokenWarning = true;
void window.showInformationMessage(`In order to use "${modelIdOrEndpoint}" through Hugging Face API Inference, you'd need Hugging Face API Token`,
"Get your token"
).then(clicked => {
if (clicked) {
void env.openExternal(Uri.parse("https://github.com/huggingface/huggingface-vscode#hf-api-token"));
}
});
}
}
inputs += endToken;

const inputs = prefix;

const data = {
inputs,
parameters: {
max_new_tokens: 256,
max_new_tokens: 60,
temperature,
do_sample: temperature > 0,
top_p: 0.95,
Expand All @@ -76,9 +77,6 @@ export default async function runCompletion(

logInput(inputs, data.parameters);

const context = getTabnineExtensionContext();
const apiToken = await context?.secrets.get("apiToken");

const headers = {
"Content-Type": "application/json",
"Authorization": "",
Expand All @@ -95,14 +93,15 @@ export default async function runCompletion(

if(!res.ok){
console.error("Error sending a request", res.status, res.statusText);
setDefaultStatus();
return null;
}

const generatedTextRaw = getGeneratedText(await res.json());

let generatedText = generatedTextRaw.replace(stopToken, "");
const indexEndToken = generatedText.indexOf(endToken)
if(indexEndToken !== -1){
generatedText = generatedText.slice(indexEndToken+endToken.length).trim();
if(generatedText.slice(0, inputs.length) === inputs){
generatedText = generatedText.slice(inputs.length);
}

const resultEntry: ResultEntry = {
Expand Down

0 comments on commit f78dbbe

Please sign in to comment.