NAME
Peta::NN::Fused - micro models fused into one, as they are, the seams inside
VERSION
version 0.2610090
SYNOPSIS
use Peta::NN::Fused;
# Apfel -> Äpfel -> Äpfeln, in one model. The steps are a pipeline's.
my $decline = Peta::NN::Fused->new(
models => { map { $_ => "deu-noun/$_.model" } qw(umlaut ending case) },
steps => [
{ model => 'umlaut', params => [ \0 ] },
{ model => 'ending', params => [ \0 ] },
{ model => 'case', params => [ \1 ] },
],
);
print scalar $decline->predict('apfel', 'masculine', 'dative'); # äpfeln
$decline->save('deu-noun-decline.fused');
my $on_the_card = Peta::NN::Fused->load('deu-noun-decline.fused', engine => 'gpu');
my @plurals = $on_the_card->predict_all(\@nouns, 'neuter', 'nominative');
# a better part, the others untouched
my $improved = $decline->replace(ending => 'deu-noun/ending-2.model');
# One model names the language of a text, and that chooses the model
# that says what each of its words is.
my $tagger = Peta::NN::Fused->new(
models => { language => 'language.model', map { $_ => "wordclass-$_.model" } qw(ces deu eng) },
steps => [
{ name => 'language', model => 'language', classify => 1, pool => 1 },
{ name => 'class', model => { language => { map { $_ => $_ } qw(ces deu eng) } }, classify => 1 },
],
);
for my $text (@{ $tagger->run_texts([ \@words_of_one_text, \@words_of_another ]) }) {
printf "%s %s %s\n", @{ $_->{answers} }{qw(language class)}, $_->{text} for @$text;
}
DESCRIPTION
Three ways to put micro models together:
- in a pipeline
-
N1 -> [Perl: the answer becomes the input] -> N2. Peta::NN::Pipeline. - fused
-
N3 = N1 -> N2: both networks as they are, in one model, the seam between them inside it. This module. No training; the fused model has the weights of its parts and answers exactly what the pipeline answers. - fused, consolidated
-
N4: one model trained on what the chain does. Smaller and faster, and a different function.
A fused model takes the steps a pipeline takes, written the same way. What a pipeline does with a step's outputs is in here an operation without weights: route takes an edit model's best label and carries its edit out on the characters kept per string, which the next part then reads; class keeps a class model's best label as the step's answer; pool does that for a whole text, whose strings then all have the one answer. An answer can choose which of several models a later step runs for a string, and can be a later model's parameter. Where a step has several models to choose from, all of them are computed, side by side, and each takes effect only on its own strings.
What is kept per string is its last reach and its first front characters. A string of any length goes in as those and its length, and comes out as one edit and its answers.
The parts stay separate, in the object and in its file. replace swaps one for a better one; the seams are derived again from the labels.
What fuses
Class models, and edit models that rewrite the end of a string (side => 'right'). Edit models that rewrite the front or both ends, and rewrite models, do not.
Where a pipeline would stop in the middle of a call, a fused model refuses when it is built: an answer a routing table has no model for, or an answer that is not a value of the parameter it is to be.
Engines
cpu computes each part as Peta::NN::Inference does, so the answers and confidences are those of the pipeline to the last bit. gpu keeps a whole batch on the graphics card from the first part to the last; it computes in 32-bit floats, so a confidence agrees to about six digits, and a decision between two labels that close can fall the other way. It needs a pperl with WebGPU and is the engine when engine => 'gpu' is given or PETA_NN_ENGINE=gpu is set.
METHODS
new
Peta::NN::Fused->new(models => { name => model }, steps => [...]), optionally with engine and meta. A model is a model file's path, model data, or an object that has it. The steps are those of "new" in Peta::NN::Pipeline.
load
Peta::NN::Fused->load($file, engine => ...): a fused model from its file.
save
save($file): writes the parts, each as it is, and the steps.
replace
replace(name => model, ...): a new fused model with those parts replaced.
predict
predict($string, @arguments): the answer; in list context also its confidence, the product of the parts'.
predict_all
predict_all(\@strings, @arguments): the answers, in order.
answers
answers(\@strings, @arguments): [answer, confidence] per string.
run
run(\@strings, @arguments): one record per string, { text, confidence, answers }, the answers being those of the steps that classify, under the steps' names.
run_texts
run_texts(\@texts, @arguments): the same for texts, each a list of strings; returns the records per text. A pooling step answers once per text.
parts
The names of the parts, in the order the steps first use them.
part
part($name): that part, as a Peta::NN::Inference model.
names
The names of the steps that classify, in order.
n_params
How many weights the fused model has: those of its parts.
reach
How many characters of a string's end the fused model reads.
front
How many characters of a string's front the fused model reads.
arguments
How many arguments a call takes after the string.
engine
cpu or gpu.
info
What there is to know about the fused model, as a table.
AUTHOR
PetaMem s.r.o. <info@petamem.com>
COPYRIGHT
Copyright (c) 2026 PetaMem s.r.o.
LICENSE
This package is free software, dual-licensed under the Artistic License 2.0 and the BSD 2-Clause License. See the LICENSE file of the distribution.