Skip to content

Commit 75b85ad

Browse files
vvmnnnkvcoyotte508
andauthored
Suggestion for endpoints (#138)
Co-authored-by: coyotte508 <[email protected]>
1 parent 1221acb commit 75b85ad

File tree

5 files changed

+68
-9
lines changed

5 files changed

+68
-9
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
This is a collection of JS libraries to interact with the Hugging Face API, with TS types included.
1515

1616
- [@huggingface/hub](packages/hub/README.md): Interact with huggingface.co to create or delete repos and commit / download files
17-
- [@huggingface/inference](packages/inference/README.md): Use the Inference API to make calls to 100,000+ Machine Learning models!
17+
- [@huggingface/inference](packages/inference/README.md): Use the Inference API to make calls to 100,000+ Machine Learning models, or to your own [inference endpoints](https://hf.co/docs/inference-endpoints/)!
1818

1919
With more to come, like `@huggingface/endpoints` to manage your HF Endpoints!
2020

@@ -102,6 +102,10 @@ await inference.imageToText({
102102
data: await (await fetch('https://picsum.photos/300/300')).blob(),
103103
model: 'nlpconnect/vit-gpt2-image-captioning',
104104
})
105+
106+
// Using your own inference endpoint: https://hf.co/docs/inference-endpoints/
107+
const gpt2 = hf.endpoint('https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2');
108+
const { generated_text } = await gpt2.textGeneration({inputs: 'The answer to the universe is'});
105109
```
106110

107111
There are more features of course, check each library's README!

packages/inference/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# 🤗 Hugging Face Inference API
22

3-
A Typescript powered wrapper for the Hugging Face Inference API. Learn more about the Inference API at [Hugging Face](https://huggingface.co/docs/api-inference/index).
3+
A Typescript powered wrapper for the Hugging Face Inference API. Learn more about the Inference API at [Hugging Face](https://huggingface.co/docs/api-inference/index). It also works with [Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index).
44

5-
Check out the [full documentation](https://huggingface.co/docs/huggingface.js/inference/README) or try out a live [interactive notebook](https://observablehq.com/@huggingface/hello-huggingface-js-inference).
5+
Check out the [full documentation](https://huggingface.co/docs/huggingface.js/inference/README).
6+
7+
You can also try out a live [interactive notebook](https://observablehq.com/@huggingface/hello-huggingface-js-inference) or see some demos on [hf.co/huggingfacejs](https://huggingface.co/huggingfacejs).
68

79
## Install
810

@@ -16,16 +18,16 @@ pnpm add @huggingface/inference
1618

1719
## Usage
1820

19-
**Important note:** Using an API key is optional to get started, however you will be rate limited eventually. Join [Hugging Face](https://huggingface.co/join) and then visit [access tokens](https://huggingface.co/settings/tokens) to generate your API key for **free**.
21+
**Important note:** Using an access token is optional to get started, however you will be rate limited eventually. Join [Hugging Face](https://huggingface.co/join) and then visit [access tokens](https://huggingface.co/settings/tokens) to generate your access token for **free**.
2022

21-
Your API key should be kept private. If you need to protect it in front-end applications, we suggest setting up a proxy server that stores the API key.
23+
Your access token should be kept private. If you need to protect it in front-end applications, we suggest setting up a proxy server that stores the access token.
2224

2325
### Basic examples
2426

2527
```typescript
2628
import { HfInference } from '@huggingface/inference'
2729

28-
const hf = new HfInference('your api key')
30+
const hf = new HfInference('your access token')
2931

3032
// Natural Language
3133

@@ -167,6 +169,10 @@ await hf.imageToText({
167169
data: readFileSync('test/cats.png'),
168170
model: 'nlpconnect/vit-gpt2-image-captioning'
169171
})
172+
173+
// Using your own inference endpoint: https://hf.co/docs/inference-endpoints/
174+
const gpt2 = hf.endpoint('https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2');
175+
const { generated_text } = await gpt2.textGeneration({inputs: 'The answer to the universe is'});
170176
```
171177

172178
## Supported Tasks

packages/inference/src/HfInference.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export interface Options {
2929
}
3030

3131
export interface Args {
32-
model: string;
32+
/**
33+
* The model to use. Optional for endpoints.
34+
*/
35+
model?: string;
3336
}
3437

3538
export type FillMaskArgs = Args & {
@@ -639,10 +642,19 @@ export interface ImageToTextReturn {
639642
export class HfInference {
640643
private readonly apiKey: string;
641644
private readonly defaultOptions: Options;
645+
private readonly endpointUrl?: string;
642646

643-
constructor(apiKey = "", defaultOptions: Options = {}) {
647+
constructor(apiKey = "", defaultOptions: Options = {}, endpointUrl?: string) {
644648
this.apiKey = apiKey;
645649
this.defaultOptions = defaultOptions;
650+
this.endpointUrl = endpointUrl;
651+
}
652+
653+
/**
654+
* Returns copy of HfInference tied to a specified endpoint.
655+
*/
656+
public endpoint(endpointUrl: string): HfInference {
657+
return new HfInference(this.apiKey, this.defaultOptions, endpointUrl);
646658
}
647659

648660
/**
@@ -1063,7 +1075,10 @@ export class HfInference {
10631075
}
10641076
}
10651077

1066-
const url = `${HF_INFERENCE_API_BASE_URL}${model}`;
1078+
if (!model && !this.endpointUrl) {
1079+
throw new Error("Model is required for Inference API");
1080+
}
1081+
const url = this.endpointUrl ? this.endpointUrl : `${HF_INFERENCE_API_BASE_URL}${model}`;
10671082
const info: RequestInit = {
10681083
headers,
10691084
method: "POST",

packages/inference/test/HfInference.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,20 @@ describe.concurrent(
397397
generated_text: "a large brown and white giraffe standing in a field ",
398398
});
399399
});
400+
it("endpoint - makes request to specified endpoint", async () => {
401+
const ep = hf.endpoint("https://api-inference.huggingface.co/models/google/flan-t5-xxl");
402+
const { generated_text } = await ep.textGeneration({
403+
inputs: "one plus two equals",
404+
});
405+
expect(generated_text).toEqual("three");
406+
});
407+
it("error when the model is not set", () => {
408+
expect(
409+
hf.textGeneration({
410+
inputs: "one plus two equals",
411+
})
412+
).rejects.toThrowError("Model is required for Inference API");
413+
});
400414
},
401415
TIMEOUT
402416
);

packages/inference/test/tapes.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,26 @@
447447
}
448448
}
449449
},
450+
"e64d5b8d2371f0706f29b4e27cac68b3f1e9fe3b10013a7f008ddbe005d7eb8f": {
451+
"url": "https://api-inference.huggingface.co/models/google/flan-t5-xxl",
452+
"init": {
453+
"headers": {
454+
"Content-Type": "application/json"
455+
},
456+
"method": "POST"
457+
},
458+
"response": {
459+
"body": "[{\"generated_text\":\"three\"}]",
460+
"status": 200,
461+
"statusText": "OK",
462+
"headers": {
463+
"access-control-allow-credentials": "true",
464+
"connection": "keep-alive",
465+
"content-type": "application/json",
466+
"vary": "Origin, Access-Control-Request-Method, Access-Control-Request-Headers"
467+
}
468+
}
469+
},
450470
"7364916c1dcc1aaf643027e0c86abcf22e3b963dd5876fce23ffa7604465899e": {
451471
"url": "https://api-inference.huggingface.co/models/sentence-transformers/distilbert-base-nli-mean-tokens",
452472
"init": {

0 commit comments

Comments
 (0)