Skip to content

➕ Add @huggingface/tasks as a dep of @huggingface/inference #651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/inference-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,44 @@ jobs:
git add ../..
git commit -m "🔖 @hugginface/inference $BUMPED_VERSION"
git tag "inference-v$BUMPED_VERSION"

- name: Make sure that the latest version of @huggingface/tasks is consistent with the local version
run: |
LOCAL_TASKS_VERSION=$(node -p "require('./package.json').version")
REMOTE_TASKS_VERSION=$(npm view @huggingface/tasks version)

# If the versions are different, error
if [ "$LOCAL_TASKS_VERSION" != "$REMOTE_TASKS_VERSION" ]; then
echo "Error: The local @huggingface/tasks package version ($LOCAL_TASKS_VERSION) differs from the remote version ($REMOTE_TASKS_VERSION). Release halted."
exit 1
fi

npm pack @huggingface/tasks
mv huggingface-tasks-$LOCAL_TASKS_VERSION.tgz tasks-local.tgz

npm pack @huggingface/tasks@$REMOTE_TASKS_VERSION
mv huggingface-tasks-$REMOTE_TASKS_VERSION.tgz tasks-remote.tgz

# Compute checksum of local tar. We need to extract both tar since the remote compression might be different
tar -xf tasks-local.tgz
LOCAL_CHECKSUM=$(cd package && tar --mtime='1970-01-01' --mode=755 -cf - . | sha256sum | cut -d' ' -f1)
echo "Local package checksum: $LOCAL_CHECKSUM"

rm -Rf package

tar -xf tasks-remote.tgz
REMOTE_CHECKSUM=$(cd package && tar --mtime='1970-01-01' --mode=755 -cf - . | sha256sum | cut -d' ' -f1)
echo "Remote package checksum: $REMOTE_CHECKSUM"

rm -Rf package

if [ "$LOCAL_CHECKSUM" != "$REMOTE_CHECKSUM" ]; then
echo "Checksum Verification Failed: The local @huggingface/tasks package differs from the remote version. Release halted. Local Checksum: $LOCAL_CHECKSUM, Remote Checksum: $REMOTE_CHECKSUM"
exit 1
fi
echo "Checksum Verification Successful: The local and remote @huggingface/tasks packages are consistent. Proceeding with the @huggingface/widgets package release. Local Checksum: $LOCAL_CHECKSUM, Remote Checksum: $REMOTE_CHECKSUM."
working-directory: packages/tasks

- run: pnpm publish --no-git-checks .
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
run: |
sleep 3
pnpm i --filter inference... --filter hub... --frozen-lockfile
pnpm --filter inference --filter hub publish --force --no-git-checks --registry http://localhost:4874/
pnpm --filter inference --filter hub --filter tasks publish --force --no-git-checks --registry http://localhost:4874/

- name: E2E test - test yarn install
working-directory: e2e/ts
Expand Down
6 changes: 4 additions & 2 deletions packages/inference/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"type": "module",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --clean && pnpm run dts",
"dts": "tsx scripts/generate-dts.ts",
"dts": "tsx scripts/generate-dts.ts && tsc --noEmit dist/index.d.ts",
"lint": "eslint --quiet --fix --ext .cjs,.ts .",
"lint:check": "eslint --ext .cjs,.ts .",
"format": "prettier --write .",
Expand All @@ -51,8 +51,10 @@
"test:browser": "vitest run --browser.name=chrome --browser.headless --config vitest.config.mts",
"check": "tsc"
},
"dependencies": {
"@huggingface/tasks": "workspace:^"
},
"devDependencies": {
"@huggingface/tasks": "workspace:^",
"@types/node": "18.13.0"
},
"resolutions": {}
Expand Down
4 changes: 3 additions & 1 deletion packages/inference/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions packages/inference/scripts/generate-dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import { readFileSync, writeFileSync, appendFileSync, readdirSync } from "node:fs";
import { TASKS_DATA } from "@huggingface/tasks";

const taskImports = new Set<string>();

const tasks = Object.keys(TASKS_DATA)
.sort()
.filter((task) => task !== "other");
Expand Down Expand Up @@ -36,6 +38,16 @@ for (const dir of dirs) {

const fileContent = readFileSync(`./src/tasks/${dir}/${file}`, "utf-8");

// detect imports from @huggingface/tasks
for (const imports of fileContent.matchAll(/import type {(.*)} from "@huggingface\/tasks";/g)) {
// Convert A, B, C to ["A", "B", "C"]
const imported = imports[1].split(",").map((x) => x.trim());

for (const imp of imported) {
taskImports.add(imp);
}
}

for (const type of extractTypesAndInterfaces(fileContent)) {
appendFileSync("./dist/index.d.ts", type + "\n");
}
Expand Down Expand Up @@ -87,6 +99,13 @@ appendFileSync(
"\n}\n"
);

// Prepend import from @huggingface/tasks
writeFileSync(
"./dist/index.d.ts",
`import type { ${[...taskImports].join(", ")} } from "@huggingface/tasks";\n` +
readFileSync("./dist/index.d.ts", "utf-8")
);

function* extractTypesAndInterfaces(fileContent: string): Iterable<string> {
let index = 0;

Expand Down
204 changes: 2 additions & 202 deletions packages/inference/src/tasks/nlp/textGeneration.ts
Original file line number Diff line number Diff line change
@@ -1,209 +1,9 @@
import type { TextGenerationInput, TextGenerationOutput } from "@huggingface/tasks";
import { InferenceOutputError } from "../../lib/InferenceOutputError";
import type { BaseArgs, Options } from "../../types";
import { request } from "../custom/request";

/**
* Inputs for Text Generation inference
*/
export interface TextGenerationInput {
/**
* The text to initialize generation with
*/
inputs: string;
/**
* Additional inference parameters
*/
parameters?: TextGenerationParameters;
/**
* Whether to stream output tokens
*/
stream?: boolean;
[property: string]: unknown;
}

/**
* Additional inference parameters
*
* Additional inference parameters for Text Generation
*/
export interface TextGenerationParameters {
/**
* The number of sampling queries to run. Only the best one (in terms of total logprob) will
* be returned.
*/
best_of?: number;
/**
* Whether or not to output decoder input details
*/
decoder_input_details?: boolean;
/**
* Whether or not to output details
*/
details?: boolean;
/**
* Whether to use logits sampling instead of greedy decoding when generating new tokens.
*/
do_sample?: boolean;
/**
* The maximum number of tokens to generate.
*/
max_new_tokens?: number;
/**
* The parameter for repetition penalty. A value of 1.0 means no penalty. See [this
* paper](https://hf.co/papers/1909.05858) for more details.
*/
repetition_penalty?: number;
/**
* Whether to prepend the prompt to the generated text.
*/
return_full_text?: boolean;
/**
* The random sampling seed.
*/
seed?: number;
/**
* Stop generating tokens if a member of `stop_sequences` is generated.
*/
stop_sequences?: string[];
/**
* The value used to modulate the logits distribution.
*/
temperature?: number;
/**
* The number of highest probability vocabulary tokens to keep for top-k-filtering.
*/
top_k?: number;
/**
* If set to < 1, only the smallest set of most probable tokens with probabilities that add
* up to `top_p` or higher are kept for generation.
*/
top_p?: number;
/**
* Truncate input tokens to the given size.
*/
truncate?: number;
/**
* Typical Decoding mass. See [Typical Decoding for Natural Language
* Generation](https://hf.co/papers/2202.00666) for more information
*/
typical_p?: number;
/**
* Watermarking with [A Watermark for Large Language Models](https://hf.co/papers/2301.10226)
*/
watermark?: boolean;
[property: string]: unknown;
}

/**
* Outputs for Text Generation inference
*/
export interface TextGenerationOutput {
/**
* When enabled, details about the generation
*/
details?: TextGenerationOutputDetails;
/**
* The generated text
*/
generated_text: string;
[property: string]: unknown;
}

/**
* When enabled, details about the generation
*/
export interface TextGenerationOutputDetails {
/**
* Details about additional sequences when best_of is provided
*/
best_of_sequences?: TextGenerationOutputSequenceDetails[];
/**
* The reason why the generation was stopped.
*/
finish_reason: TextGenerationFinishReason;
/**
* The number of generated tokens
*/
generated_tokens: number;
prefill: TextGenerationPrefillToken[];
/**
* The random seed used for generation
*/
seed?: number;
/**
* The generated tokens and associated details
*/
tokens: TextGenerationOutputToken[];
/**
* Most likely tokens
*/
top_tokens?: Array<TextGenerationOutputToken[]>;
[property: string]: unknown;
}

export interface TextGenerationOutputSequenceDetails {
finish_reason: TextGenerationFinishReason;
/**
* The generated text
*/
generated_text: string;
/**
* The number of generated tokens
*/
generated_tokens: number;
prefill: TextGenerationPrefillToken[];
/**
* The random seed used for generation
*/
seed?: number;
/**
* The generated tokens and associated details
*/
tokens: TextGenerationOutputToken[];
/**
* Most likely tokens
*/
top_tokens?: Array<TextGenerationOutputToken[]>;
[property: string]: unknown;
}

export interface TextGenerationPrefillToken {
id: number;
logprob: number;
/**
* The text associated with that token
*/
text: string;
[property: string]: unknown;
}

/**
* Generated token.
*/
export interface TextGenerationOutputToken {
id: number;
logprob?: number;
/**
* Whether or not that token is a special one
*/
special: boolean;
/**
* The text associated with that token
*/
text: string;
[property: string]: unknown;
}

/**
* The reason why the generation was stopped.
*
* length: The generated sequence reached the maximum allowed length
*
* eos_token: The model generated an end-of-sentence (EOS) token
*
* stop_sequence: One of the sequence in stop_sequences was generated
*/
export type TextGenerationFinishReason = "length" | "eos_token" | "stop_sequence";
export type { TextGenerationInput, TextGenerationOutput };

/**
* Use to continue text from a prompt. This is a very generic task. Recommended model: gpt2 (it’s a simple model, but fun to play with).
Expand Down
2 changes: 1 addition & 1 deletion packages/inference/src/tasks/nlp/textGenerationStream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { TextGenerationInput } from "@huggingface/tasks";
import type { BaseArgs, Options } from "../../types";
import { streamingRequest } from "../custom/streamingRequest";
import type { TextGenerationInput } from "./textGeneration";

export interface TextGenerationStreamToken {
/** Token ID from the model tokenizer */
Expand Down