A comprehensive PHP client for the Hugging Face Hub. Access thousands of machine learning models, datasets, run inference, and more, all from your PHP application.
- Hub API: Full CRUD support for Repositories (Models, Datasets, Spaces), Files, and Collections.
- Inference API: Run inference on over 100,000+ models using Hugging Face's serverless abstraction. Automatically resolves the best provider for you.
- Smart Caching: Built-in, OS-aware caching system with support for generic file caching and optimization.
- Type-Safe: Fully typed DTOs for strict typing and better developer experience.
- Utilities: Includes specific utilities for various tasks like token classification, zero-shot classification, and more.
use Codewithkyrian\HuggingFace\HuggingFace;
$hf = HuggingFace::client();
// Download a model config
$config = $hf->hub()->repo('bert-base-uncased')
->download('config.json')
->json();
// List models
$models = $hf->hub()->models()
->search('sentiment')
->limit(5)
->get();
// Chat with an LLM
$response = $hf->inference()
->chatCompletion('meta-llama/Llama-3.1-8B-Instruct')
->system('You are a helpful assistant.')
->user('What is PHP?')
->generate();
// Generate embeddings
$embeddings = $hf->inference()
->featureExtraction('sentence-transformers/all-MiniLM-L6-v2')
->normalize()
->execute('Hello world');- Installation
- Quick Start
- Configuration
- Hub API
- Inference API
- Provider Configuration
- Chat Completion
- Text Generation
- Feature Extraction (Embeddings)
- Text Classification
- Token Classification
- Summarization
- Question Answering
- Translation
- Fill Mask
- Sentence Similarity
- Text to Image
- Image Classification
- Object Detection
- Image to Text
- Text to Speech
- Automatic Speech Recognition
- Caching
- Error Handling
- Examples
- API Reference
Install the package via Composer:
composer require codewithkyrian/huggingface- PHP 8.2 or higher
- A PSR-18 HTTP client (e.g., Guzzle, Symfony HttpClient)
If you don't have a PSR-18 client installed, add Guzzle:
composer require guzzlehttp/guzzleThe client works without authentication for public resources:
<?php
require 'vendor/autoload.php';
use Codewithkyrian\HuggingFace\HuggingFace;
$hf = HuggingFace::client();
// Download a model file
$config = $hf->hub()
->repo('bert-base-uncased')
->download('config.json')
->json();
echo "Model type: {$config['model_type']}\n";
// List models
$models = $hf->hub()
->models()
->search('text-classification')
->library('transformers')
->limit(5)
->get();
foreach ($models->items as $model) {
echo "{$model->id} - {$model->downloads} downloads\n";
}
// List files in a repository
$files = $hf->hub()->repo('gpt2')->files();
foreach ($files as $file) {
echo "{$file->path} ({$file->size} bytes)\n";
}
// Work with specific revisions
$v1Repo = $hf->hub()->repo('gpt2')->revision('v1.0');
$info = $v1Repo->info();
$files = $v1Repo->files();For operations requiring authentication (private repos, inference, uploads), provide a token:
$hf = HuggingFace::client('hf_your_token');
// Run inference
$classifier = $hf->inference()->textClassification('distilbert-base-uncased-finetuned-sst-2-english');
$results = $classifier->execute('I love this product!');
echo $results[0]->label; // "POSITIVE"A token is optional for public Hub operations (downloading, searching, listing). You need a token for:
- Accessing private repositories
- Running inference on most models
- Uploading files or creating repositories
Getting a token:
- Create a free account at huggingface.co
- Go to Settings → Access Tokens
- Create a token with appropriate permissions
use Codewithkyrian\HuggingFace\HuggingFace;
// Without token (public operations only)
$hf = HuggingFace::client();
// With token
$hf = HuggingFace::client('hf_your_token_here');The client automatically checks these environment variables:
// Set HF_TOKEN or HUGGING_FACE_HUB_TOKEN in your environment
$hf = HuggingFace::client(); // Token loaded automaticallyUse the factory for full control:
$hf = HuggingFace::factory()
->withToken('hf_your_token') // Optional
->withCacheDir('/path/to/cache') // Custom cache directory
->withHubUrl('https://custom.hf') // Custom Hub endpoint
->make();The Hub API lets you manage repositories, upload models, and search the Hugging Face Hub.
Get a RepoManager for any repository. All operations (info, files, download, commit) flow through it.
use Codewithkyrian\HuggingFace\Enums\RepoType;
$hub = $hf->hub();
$repo = $hub->repo('bert-base-uncased'); // Model (default)
$repo = $hub->repo('squad', RepoType::Dataset); // Dataset
$repo = $hub->repo('gradio/hello-world', RepoType::Space); // SpaceBy default, operations use the main branch. Use revision() to target a specific branch, tag, or commit.
$repo = $hub->repo('bert-base-uncased');
$v1Repo = $repo->revision('v1.0');
$info = $v1Repo->info();
$files = $v1Repo->files();Get metadata about a repository.
$repo = $hub->repo('bert-base-uncased');
$info = $repo->info();
echo $info->id; // "bert-base-uncased"
echo $info->downloads; // 12345678Shorthand methods when you only need metadata:
$modelInfo = $hub->modelInfo('bert-base-uncased');
$datasetInfo = $hub->datasetInfo('squad');
$spaceInfo = $hub->spaceInfo('gradio/hello-world');use Codewithkyrian\HuggingFace\Enums\RepoType;
use Codewithkyrian\HuggingFace\Enums\SpaceSdk;
// Model repository
$repo = $hub->createRepo('my-model', RepoType::Model)
->private()
->license('mit')
->save();
// Dataset
$repo = $hub->createRepo('my-dataset', RepoType::Dataset)->save();
// Space
$repo = $hub->createRepo('my-space', RepoType::Space)
->sdk(SpaceSdk::Gradio, '4.0.0')
->save();| Method | Description |
|---|---|
private() |
Make repository private |
license(string $id) |
Set license (e.g., mit, apache-2.0) |
sdk(SpaceSdk $sdk, string $version) |
Set Space SDK and version (for spaces only) |
hardware(SpaceHardware $hw) |
Set Space hardware tier (for spaces only) |
use Codewithkyrian\HuggingFace\Enums\Visibility;
$repo = $hub->repo('username/my-model');
$repo->setVisibility(Visibility::Public);
$repo->update([
'description' => 'Updated description',
'tags' => ['pytorch', 'text-classification'],
]);$repo = $hub->repo('username/my-model');
// Check existence
if ($repo->exists()) {
echo "Repository exists";
}
// Check access
$repo->checkAccess(); // Throws AuthenticationException or ApiException if denied
// Rename/move
$renamedRepo = $repo->move('new-name');
// Fork
$forkedRepo = $repo->fork();
$forkedRepo = $repo->fork(targetNamespace: 'my-org');
// Delete
$repo->delete();
$repo->delete(missingOk: true); // Don't throw if not found$repo = $hub->repo('username/my-model');
// Create branches
$repo->createBranch('feature-x');
$repo->createBranch('feature-y', revision: 'v1.0');
$repo->createBranch('empty-branch', empty: true);
// Delete branch
$repo->deleteBranch('old-branch');
// List branches and tags
$branches = $repo->branches();
$tags = $repo->tags();
$refs = $repo->refs(); // All refs (branches, tags, converts)// Throws if repo is not found
$hub->repo('username/my-model')->delete();
// Don't throw if not found
$hub->repo('username/maybe-exists')->delete(missingOk: true);$repo = $hub->repo('bert-base-uncased');
$files = $repo->files(); // returns Generator
foreach ($files as $file) {
echo "{$file->path} ({$file->size} bytes)\n";
}| Method | Description |
|---|---|
files(recursive: true) |
Include files in subdirectories |
files(expand: true) |
Include expanded metadata |
files(path: 'subdir') |
List files in specific directory |
$repo = $hub->repo('bert-base-uncased');
// Check existence
$exists = $repo->fileExists('config.json');
// Single file info
$info = $repo->fileInfo('config.json');
echo $info->size;
echo $info->oid;
echo $info->isLfs();
// Multiple files
$filesInfo = $repo->pathsInfo(['config.json', 'model.safetensors']);$repo = $hub->repo('bert-base-uncased');
// Download to directory
$path = $repo->download('config.json')->save('/local/path');
// Download to cache (returns cached path)
$cachedPath = $repo->download('config.json')->save();
// Get content directly
$content = $repo->download('config.json')->getContent();
// Parse as JSON
$config = $repo->download('config.json')->json();
// Get metadata only
$info = $repo->download('config.json')->info();
echo "Size: {$info->size} bytes";
echo "ETag: {$info->etag}";| Method | Description |
|---|---|
force() |
Re-download even if cached |
useCache(false) |
Skip cache entirely |
save(?string $path) |
Save to directory, or cache if null |
getContent() |
Get raw content as string |
json() |
Parse content as JSON |
$repo = $hub->repo('bert-base-uncased');
$isCached = $repo->isCached('config.json');
$path = $repo->getCachedPath('config.json'); // null if not cachedDownload all files to a local cached snapshot.
$repo = $hub->repo('bert-base-uncased');
$snapshotPath = $repo->snapshot();
// With filtering
$snapshotPath = $repo->snapshot(
allowPatterns: ['*.json', '*.txt'],
ignorePatterns: ['*.bin', '*.safetensors']
);
// Optimized (skip network check)
$snapshotPath = $repo->snapshot(force: false);Snapshots are additive, so you can call snapshot() multiple times to build up a local content cache. Use force: false to skip the remote update check if you already have a cached revision.
$repo = $hub->repo('username/my-model');
// Single file
$repo->uploadFile('config.json', json_encode($config));
$repo->uploadFile('model.bin', '/local/path/model.bin');
// Multiple files
$repo->uploadFiles([
'config.json' => json_encode($config),
'model.bin' => '/local/path/model.bin',
]);For complex operations, use the commit builder:
$repo->commit('Add model files')
->addFile('config.json', json_encode($config))
->addFile('model.bin', '/local/path/model.bin')
->addFile('readme.md', fopen('readme.md', 'r'))
->push();addFile() accepts: string (content or path), URL, or resource (stream).
$repo = $hub->repo('username/my-model');
// Single file
$repo->deleteFile('old-file.txt');
// Multiple files
$repo->deleteFiles(['file1.txt', 'file2.txt']);
// Combined with uploads
$repo->commit('Update files')
->addFile('new.json', $content)
->deleteFile('old.json')
->push();$repo = $hub->repo('bert-base-uncased');
$commits = $repo->commits(batchSize: 50);
foreach ($commits as $commit) {
echo $commit->commit->title;
echo $commit->commit->date;
}
$totalCommits = $repo->commitCount();Note
commits() returns a Generator that fetches pages lazily. The batchSize argument (1–1000) controls how many commits are fetched per API request; the generator keeps requesting more pages until all commits are returned, so use a break when you have enough results.
Collections are curated lists of models, datasets, spaces, or papers.
$collections = $hub->collections()
->search('bert')
->owner('huggingface')
->limit(10)
->get();
foreach ($collections as $collection) {
echo "{$collection->title} ({$collection->slug})\n";
}$collection = $hub->createCollection('My Favorite Models')
->description('A curated list of awesome models')
->private()
->save();use Codewithkyrian\HuggingFace\Enums\CollectionItemType;
$collection = $hub->collection('my-collection-slug');
$info = $collection->info();
$collection->addItem('bert-base-uncased', CollectionItemType::Model, note: 'Great for NLP');
$collection->deleteItem('item-object-id');
$collection->delete();Search returns a Generator that fetches results lazily.
use Codewithkyrian\HuggingFace\Enums\SortField;
$models = $hub->models()
->search('sentiment')
->task('text-classification')
->library('transformers')
->author('huggingface')
->language('en')
->sort(SortField::Downloads)
->descending()
->limit(20)
->get();
foreach ($models as $model) {
echo "{$model->id}: {$model->downloads} downloads\n";
}| Method | Description |
|---|---|
search(string $query) |
Full-text search |
task(string $task) |
Filter by pipeline task |
library(string $lib) |
Filter by library (e.g., transformers) |
author(string $author) |
Filter by author/organization |
language(string $lang) |
Filter by language code |
sort(SortField $field) |
Sort by downloads, likes, etc. |
descending() |
Sort in descending order |
limit(int $n) |
Maximum results to fetch |
$datasets = $hub->datasets()
->search('summarization')
->author('huggingface')
->limit(10)
->get();
foreach ($datasets as $dataset) {
echo $dataset->id;
}$spaces = $hub->spaces()
->search('gradio')
->limit(10)
->get();
foreach ($spaces as $space) {
echo "{$space->id} ({$space->sdk})\n";
}Warning
Without limit(), the generator fetches ALL matching results. Always set a limit or break manually.
The Inference API lets you run machine learning models on Hugging Face's infrastructure. It supports text generation, embeddings, classification, image generation, speech recognition, and more.
The inference client supports multiple providers. Pass the provider directly to inference():
use Codewithkyrian\HuggingFace\Inference\Enums\InferenceProvider;
// Default: Auto resolved
$inference = $hf->inference();
// External provider (enum)
$inference = $hf->inference(InferenceProvider::Together);
// External provider (string slug)
$inference = $hf->inference('groq');
$inference = $hf->inference('nebius');
// Custom endpoint URL
$inference = $hf->inference('https://your-endpoint.huggingface.cloud');| Provider | Slug | Tasks |
|---|---|---|
| Hugging Face | hf-inference (default) |
All tasks |
| Black Forest Labs | black-forest-labs |
Text-to-Image |
| Cerebras | cerebras |
Chat |
| Cohere | cohere |
Chat |
| Fal.ai | fal-ai |
Text-to-Image, Text-to-Video, Image-to-Image, Image-to-Video, ASR, TTS |
| Featherless AI | featherless-ai |
Chat, Text Generation |
| Fireworks AI | fireworks-ai |
Chat |
| Groq | groq |
Chat, Text Generation |
| Hyperbolic | hyperbolic |
Chat, Text Generation, Text-to-Image |
| Nebius | nebius |
Chat, Text Generation, Text-to-Image, Embeddings |
| Novita | novita |
Chat, Text Generation |
| Nscale | nscale |
Chat, Text-to-Image |
| OpenAI | openai |
Chat (requires direct API key) |
| OVHcloud | ovhcloud |
Chat, Text Generation |
| Replicate | replicate |
Text-to-Image |
| Sambanova | sambanova |
Chat, Embeddings |
| Scaleway | scaleway |
Chat, Text Generation, Embeddings |
| Together AI | together |
Chat, Text Generation, Text-to-Image |
| ZAI | zai-org |
Chat, Text-to-Image |
When you don't specify a provider (or use InferenceProvider::Auto), the client automatically selects the best available provider for your model. Here's how it works:
- Map Model Providers: The client queries the Hugging Face Hub to find all providers that serve this model following the priority order of providers you've configured in your Inference Provider settings on Hugging Face.
- Availability & Compatibility: It selects the first provider that is currently available and supports the requested task.
- Exception: If no viable provider is found for the model and task, a
RoutingExceptionis thrown.
This ensures you always get the most reliable inference endpoint based on your personal or organization settings.
Bill requests to an organization:
$chat = $hf->inference(InferenceProvider::Together)
->billTo('my-org-id')
->chatCompletion('meta-llama/Llama-3.1-8B-Instruct');Chat with large language models using a conversational interface. Supports system prompts, multi-turn conversations, and streaming.
$chat = $hf->inference()->chatCompletion('meta-llama/Llama-3.1-8B-Instruct');
$response = $chat
->system('You are a helpful assistant.')
->user('What is PHP?')
->maxTokens(200)
->generate();
echo $response->content();
echo $response->finishReason(); // "stop", "length", etc.$response = $chat
->system('You are a coding tutor.')
->user('What is a variable?')
->assistant('A variable is a named container that stores a value.')
->user('Give me a PHP example.')
->generate();$stream = $chat
->system('You are a storyteller.')
->user('Tell me a short story.')
->maxTokens(500)
->stream();
foreach ($stream as $chunk) {
echo $chunk->choices[0]->delta->content ?? '';
}| Method | Description |
|---|---|
system(string $content) |
Add a system message |
user(string $content) |
Add a user message |
assistant(string $content) |
Add an assistant message |
maxTokens(int $tokens) |
Maximum tokens to generate |
temperature(float $temp) |
Sampling temperature (0.0–2.0) |
topP(float $p) |
Nucleus sampling probability |
topK(int $k) |
Top-k sampling |
stop(array $sequences) |
Stop sequences |
seed(int $seed) |
Random seed for reproducibility |
frequencyPenalty(float $penalty) |
Reduce repetition of tokens |
presencePenalty(float $penalty) |
Encourage new topics |
logprobs(bool $b, ?int $k) |
Return log probabilities |
responseFormat(array $fmt) |
Set response format (e.g. JSON) |
tool(ChatCompletionTool $tool) |
Add a tool definition |
tools(array<ChatCompletionTool> $tools) |
Add multiple tools |
toolChoice(string|array $c) |
Control tool choice |
Generate text continuations from a prompt. Unlike chat completion, this is for raw text completion without conversation structure.
$generator = $hf->inference()->textGeneration('gpt2');
$response = $generator
->maxNewTokens(100)
->temperature(0.7)
->execute('The future of AI is');
echo $response->generatedText;| Method | Description |
|---|---|
maxNewTokens(int $n) |
Max new tokens to generate |
temperature(float $t) |
Sampling temperature |
topK(float $k) |
Top-k sampling |
topP(float $p) |
Nucleus sampling |
repetitionPenalty(float $p) |
Repetition penalty (> 1.0) |
doSample(bool $b) |
Enable/disable sampling |
returnFullText(bool $b) |
Include prompt in output |
seed(int $s) |
Random seed |
stop(string|array $s) |
Stop sequence(s) |
truncate(int $t) |
Truncate inputs to size |
watermark(bool $b) |
Enable watermarking |
frequencyPenalty(float $p) |
Frequency penalty |
bestOf(int $n) |
Generate best of N sequences |
decoderInputDetails(bool $b) |
Return decoder input details |
Also supports: adapterId, details, grammar, topNTokens, typicalP
Generate vector embeddings for text. Useful for semantic search, clustering, and similarity comparisons.
$embedder = $hf->inference()->featureExtraction('sentence-transformers/all-MiniLM-L6-v2');
// Single text
$embedding = $embedder->execute('Hello world');
echo count($embedding); // e.g., 384 dimensions
// Batch processing
$embeddings = $embedder->execute([
'First sentence',
'Second sentence',
'Third sentence',
]);| Method | Description |
|---|---|
normalize() |
Normalize embeddings to unit length |
truncate() |
Truncate input to model's max length |
promptName(string $name) |
Use a specific prompt template |
truncationDirection(TruncationDirection $direction) |
Left or Right truncation |
Classify text into categories. Returns scored labels.
$classifier = $hf->inference()->textClassification('distilbert-base-uncased-finetuned-sst-2-english');
$results = $classifier->execute('I absolutely love this product!');
foreach ($results as $result) {
echo "{$result->label}: " . round($result->score * 100, 2) . "%\n";
}
// POSITIVE: 99.87%
// NEGATIVE: 0.13%| Method | Description |
|---|---|
topK(int $k) |
Number of predictions to return |
functionToApply(ClassificationOutputTransform $f) |
Function to apply to scores (Sigmoid, Softmax, None) |
Classify individual tokens in a text, such as identifying entities (NER) or parts of speech (POS).
use Codewithkyrian\HuggingFace\Inference\Enums\AggregationStrategy;
$ner = $hf->inference()->tokenClassification('dbmdz/bert-large-cased-finetuned-conll03-english');
$results = $ner
->aggregationStrategy(AggregationStrategy::Simple)
->execute('My name is Sarah and I live in London');
foreach ($results as $result) {
echo "{$result->word}: {$result->entityGroup} ({$result->score})\n";
}
// Sarah: PER (0.99)
// London: LOC (0.99)| Method | Description |
|---|---|
aggregationStrategy(AggregationStrategy $s) |
Strategy to fuse tokens (None, Simple, First, Average, Max) |
ignoreLabels(array $labels) |
List of labels to ignore during classification |
stride(int $n) |
Overlap tokens between chunks for long text |
Summarize long text into shorter versions.
$summarizer = $hf->inference()->summarization('facebook/bart-large-cnn');
$result = $summarizer
->maxLength(130)
->minLength(30)
->execute($longArticle);
echo $result->summaryText;| Method | Description |
|---|---|
maxLength(int $length) |
Maximum summary length |
minLength(int $length) |
Minimum summary length |
doSample(bool $sample) |
Enable sampling for varied output |
temperature(float $temp) |
Sampling temperature |
Extract answers from a context passage.
$qa = $hf->inference()->questionAnswering('deepset/roberta-base-squad2');
$context = "PHP was created by Rasmus Lerdorf in 1994.";
$result = $qa->execute('Who created PHP?', $context);
echo $result->answer; // "Rasmus Lerdorf"
echo $result->score; // Confidence score
echo $result->start; // Start position in context
echo $result->end; // End position in context| Method | Description |
|---|---|
topK(int $k) |
Number of answers to return |
docStride(int $n) |
Overlap size for long context chunks |
maxAnswerLen(int $n) |
Max answer length |
maxQuestionLen(int $n) |
Max question length |
maxSeqLen(int $n) |
Max chunk length (context + question) |
alignToWords(bool $b) |
Align answer to words (true by default) |
handleImpossibleAnswer(bool $b) |
Accept impossible answers |
Translate text between languages. Model determines the language pair.
$translator = $hf->inference()->translation('Helsinki-NLP/opus-mt-en-fr');
$result = $translator->execute('Hello, how are you?');
echo $result->translationText; // "Bonjour, comment allez-vous?"| Method | Description |
|---|---|
srcLang(string $lang) |
Source language code |
tgtLang(string $lang) |
Target language code |
maxNewTokens(int $n) |
Max new tokens to generate |
temperature(float $t) |
Sampling temperature |
doSample(bool $b) |
Enable sampling |
cleanUpTokenizationSpaces(bool $b) |
Clean up spaces |
truncation(TruncationStrategy $s) |
Truncation strategy |
Supports other generation parameters like topK, topP, etc.
Predict masked tokens in text (like BERT's pre-training task).
$mask = $hf->inference()->fillMask('bert-base-uncased');
$results = $mask->execute('Paris is the [MASK] of France.');
foreach ($results as $result) {
echo "{$result->tokenStr}: " . round($result->score * 100, 2) . "%\n";
echo " → {$result->sequence}\n";
}
// capital: 85.42%
// → paris is the capital of france.| Method | Description |
|---|---|
topK(int $k) |
Number of predictions to return |
targets(array $targets) |
Limit predictions to specific words |
Compare a source sentence against multiple target sentences.
$similarity = $hf->inference()->sentenceSimilarity('sentence-transformers/all-MiniLM-L6-v2');
$scores = $similarity->execute(
'I love cats',
['I love dogs', 'I hate cats', 'The weather is nice']
);
// $scores = [0.92, 0.45, 0.12]Generate images from text prompts.
$imageGen = $hf->inference()->textToImage('black-forest-labs/FLUX.1-schnell');
$imageData = $imageGen
->numInferenceSteps(20)
->guidanceScale(7.5)
->execute('A serene lake surrounded by mountains at sunset');
file_put_contents('output.png', $imageData);
// Or save directly
$imageGen->save('A beautiful sunset', 'sunset.png');| Method | Description |
|---|---|
numInferenceSteps(int $steps) |
Number of denoising steps |
guidanceScale(float $scale) |
How closely to follow the prompt |
width(int $px) |
Output image width |
height(int $px) |
Output image height |
size(int $w, int $h) |
Set both width and height |
seed(int $seed) |
Random seed for reproducibility |
negativePrompt(string $prompt) |
What to avoid in the image |
Classify images into categories.
$classifier = $hf->inference()->imageClassification('google/vit-base-patch16-224');
// From URL
$results = $classifier->execute('https://example.com/cat.jpg');
// From base64
$results = $classifier->execute(base64_encode(file_get_contents('cat.jpg')));
foreach ($results as $result) {
echo "{$result->label}: " . round($result->score * 100, 2) . "%\n";
}| Method | Description |
|---|---|
topK(int $k) |
Number of predictions to return |
functionToApply(ClassificationOutputTransform $f) |
Function to apply to scores (Sigmoid, Softmax, None) |
Detect objects in an image with bounding boxes.
$detector = $hf->inference()->objectDetection('facebook/detr-resnet-50');
// From URL or file path
$results = $detector->execute('https://example.com/photo.jpg');
foreach ($results as $result) {
echo "Label: {$result->label}, Score: " . round($result->score, 4) . "\n";
echo "Box: [{$result->box->xmin}, {$result->box->ymin}, {$result->box->xmax}, {$result->box->ymax}]\n";
}| Method | Description |
|---|---|
threshold(float $threshold) |
Probability threshold to make a prediction |
Generate captions for images.
$captioner = $hf->inference()->imageToText('Salesforce/blip-image-captioning-base');
$result = $captioner->execute('https://example.com/photo.jpg');
echo $result->generatedText; // "a dog playing in the park"| Method | Description |
|---|---|
maxNewTokens(int $n) |
Max new tokens to generate |
temperature(float $t) |
Sampling temperature |
doSample(bool $b) |
Enable sampling |
topK(int $k) |
Top-k sampling |
topP(float $p) |
Nucleus sampling |
minNewTokens(int $n) |
Min new tokens to generate |
numBeams(int $n) |
Number of beams for beam search |
Supports other standard generation parameters: earlyStopping, numBeamGroups, penaltyAlpha, useCache, etaCutoff, epsilonCutoff, typicalP
Convert text to audio.
$tts = $hf->inference()->textToSpeech('espnet/kan-bayashi_ljspeech_vits');
$audioData = $tts->execute('Hello, how are you today?');
file_put_contents('output.wav', $audioData);
// Or save directly
$tts->save('Hello world', 'greeting.wav');| Method | Description |
|---|---|
maxNewTokens(int $n) |
Max new tokens to generate |
temperature(float $t) |
Sampling temperature |
doSample(bool $b) |
Enable sampling |
topK(int $k) |
Top-k sampling |
topP(float $p) |
Nucleus sampling |
minNewTokens(int $n) |
Min new tokens to generate |
numBeams(int $n) |
Number of beams for beam search |
Supports other standard generation parameters: earlyStopping, numBeamGroups, penaltyAlpha, useCache, etaCutoff, epsilonCutoff, typicalP
Transcribe audio to text.
$transcriber = $hf->inference()->automaticSpeechRecognition('openai/whisper-large-v3');
// From file path
$result = $transcriber->execute('/path/to/audio.mp3');
// From base64 data
$result = $transcriber->execute('data:audio/mpeg;base64,...');
echo $result->text;Classify text into arbitrary categories without training.
$zeroShot = $hf->inference()->zeroShotClassification('facebook/bart-large-mnli');
$results = $zeroShot->execute(
'I need to book a flight to New York',
['travel', 'finance', 'technology', 'sports']
);
foreach ($results as $result) {
echo "{$result->label}: " . round($result->score * 100, 2) . "%\n";
}| Method | Description |
|---|---|
multiLabel(bool $enable) |
Allow multiple labels to be true |
hypothesisTemplate(string $template) |
Custom hypothesis template |
The library uses a unified repository-based cache system with blob deduplication. This means:
- Files are stored once by their content hash (blob storage)
- Multiple snapshots share the same blob files via symlinks
- Files are only re-downloaded when they change on the server
- Repeated downloads are instant
- Zero-latency file checks using local manifests
- Your internet connection isn't required for cached files
<cacheDir>/
└── models--openai-community--gpt2/
├── blobs/ # Deduplicated file storage (by content hash)
├── snapshots/ # Snapshot pointers (symlinks to blobs)
│ └── <commitSha>/
│ └── config.json -> ../../../blobs/<hash>
└── refs/ # Revision mappings (branch/tag -> commit SHA)
└── main -> <commitSha>
You can inspect and manage the cache programmatically:
// List all cached repositories
$repos = $hf->cache()->list();
foreach ($repos as $repo) {
echo "{$repo['id']} ({$repo['type']}): " . round($repo['size'] / 1024 / 1024, 2) . " MB\n";
}
// Delete a specific repository (frees up space)
$hf->cache()->delete('google/bert-base-uncased');
// Clear the entire cache (use with caution!)
$hf->cache()->clear();The cache is stored in a platform-appropriate location:
- Linux:
~/.cache/huggingface/hubor$XDG_CACHE_HOME/huggingface/hub - macOS:
~/Library/Caches/huggingface/hub - Windows:
%LOCALAPPDATA%\huggingface\hub
You can override with the HF_HUB_CACHE or HF_HOME environment variables.
$hf = HuggingFace::factory()
->withToken('token')
->withCacheDir('/custom/cache/path')
->make();// Download single file to cache
$cachedPath = $hub->repo('model')
->download('config.json')
->save();
// Check if file is cached
$isCached = $hub->repo('model')
->isCached('config.json');
// Get cached file path
$cachedPath = $hub->repo('model')
->getCachedPath('config.json');$content = $hub->repo('model')
->download('file.bin')
->useCache(false)
->getContent();$content = $hub->repo('model')
->download('file.bin')
->force()
->getContent();The library uses specific exception types for different error conditions:
use Codewithkyrian\HuggingFace\Exceptions\{
HuggingFaceException,
AuthenticationException,
RateLimitException,
NotFoundException,
ApiException,
NetworkException
};
try {
$modelInfo = $hf->hub()->modelInfo('gp2');
} catch (AuthenticationException $e) {
// Invalid or expired token
echo "Auth error: " . $e->getMessage();
} catch (RateLimitException $e) {
// Too many requests
echo "Rate limited. Retry after: " . $e->retryAfter . " seconds";
} catch (NotFoundException $e) {
// Model or resource not found
echo "Not found: " . $e->getMessage();
} catch (NetworkException $e) {
// Connection issues
echo "Network error: " . $e->getMessage();
} catch (ApiException $e) {
// Other API errors
echo "API error ({$e->statusCode}): " . $e->getMessage();
}The library automatically retries on transient failures:
- Server errors (5xx): Retried with exponential backoff
- Rate limits (429): Retried after the
Retry-Afterdelay - Network failures: Retried up to 3 times
This happens transparently so you don't need to implement retry logic yourself.
The examples/ directory contains ready-to-run scripts:
| Directory | Description |
|---|---|
examples/hub/ |
Hub operations (search, download, upload) |
examples/inference/ |
Inference API examples for all tasks |
Run any example:
HF_TOKEN=your_token php examples/inference/chat_completion.php
php examples/hub/search.phpSee the API Reference for complete documentation of all classes and methods.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License. See LICENSE for details.