It's not ignorant. It is a known problem. Before LLMs, approaches to machine translation or any high level language tasks did start with a pipeline (part of speech tagging, dependency tree parsing, named entity recognition etc.) but quickly these attempts were discarded.
All of the models in the pipeline are not optimized with the joint loss (the final machine translation model that maps lang A to lang B does not propagate its error to the low level models in the pipeline).
A pipeline of LLMs will accumulate the error in the same way, eventually the same underlying problem of pipeline not being trained with the joint loss will result in low accuracy.
LLMs or DNNs in general do more compute, so they start being extremely powerful even when sequenced. Making a sequence of decisions with a regular ML model has a similar problem to pipelining, if you train it on single decision loss and not the sequence of decisions loss, then there's a question of can it recover and make a right next step if it made the wrong step (your training data never included this recovery example), but convolutional NNs were so powerful for language tasks that this recovery from error was successful (even though you never trained CNNs over the joint loss of sequence of decision).
It's not a given that the performance would suffer. For instance, you could use self-checking methods like cycle consistency or back translation in a sequence of prompts. Another option is to generate multiple answers and then use a voting system to pick the best one. This could actually boost the LLM's accuracy, although it would require more computation. In various tasks, there might be simpler methods for verifying the answer than initially generating it.
Then you have techniques like the Tree of Thoughts, which are particularly useful for tasks that require strategic planning and exploration. You just can't solve these in one single round of LLM interaction.
In real-world applications, developers often choose a series of prompts that enable either self-checking or error minimization. Alternatively, they can involve a human in the loop to guide the system's actions. The point is to design with the system's limitations in mind.
On a side note, if you're using vLLM, you can send up to 20 requests in parallel without incurring additional costs. The server batches these requests and uses key-value caching, so you get high token/s throughput. This allows you to resend previous outputs for free or run multiple queries on a large text segment. So, running many tasks doesn't necessarily slow things down if you manage it correctly.
It is a simple problem and in literature it was named "label bias".
Let's say you maximize performance of a single piece of pipeline (training on a dataset or something else), and you do it the same way for all pieces. The labels that were correct as inputs in training are your limitation. Why? Because when a mistake happens, you've never learned to recover from it, because you always gave the correct labels in your training.
What LLM pipelines do is probably something like this:
* a complex task is solved by a pipeline of prompts
* we tweak a single prompt
* we observe the output at the end of the whole pipeline and determine if the tweak was right
In this way, the joint loss of the pipeline is observed and that is ok.
But, the moment your pipeline is:
POS Tagger -> Dependency Tree Parser -> Named Entity Recognition -> ... -> Machine Translation
and you have separate training sets that maximize performance of each particular piece, you are introducing label bias and are relying on some luck to recover from errors early in the pipeline because during training, the later parts never got errors as input and recovered to the correct output.
You probably know this but you definitely don't have to run into that problem. In practice most people who use one component to produce features for another will take care to ensure errors are present in the pipeline. So the conceptually simple (but operationally annoying) way to do this is to train your POS tagger or whatever on multiple folds, and predict the missing fold. This is known as "jack-knife training" in the literature.
In spaCy what we do is just train the components in sequence. So everything is trained at the same time, and in the early iterations the model is seeing samples with errors. I've always found this to be good enough.
Comments
It's not ignorant. It is a known problem. Before LLMs, approaches to machine translation or any high level language tasks did start with a pipeline (part of speech tagging, dependency tree parsing, named entity recognition etc.) but quickly these attempts were discarded.
All of the models in the pipeline are not optimized with the joint loss (the final machine translation model that maps lang A to lang B does not propagate its error to the low level models in the pipeline).
A pipeline of LLMs will accumulate the error in the same way, eventually the same underlying problem of pipeline not being trained with the joint loss will result in low accuracy.
LLMs or DNNs in general do more compute, so they start being extremely powerful even when sequenced. Making a sequence of decisions with a regular ML model has a similar problem to pipelining, if you train it on single decision loss and not the sequence of decisions loss, then there's a question of can it recover and make a right next step if it made the wrong step (your training data never included this recovery example), but convolutional NNs were so powerful for language tasks that this recovery from error was successful (even though you never trained CNNs over the joint loss of sequence of decision).
It's not a given that the performance would suffer. For instance, you could use self-checking methods like cycle consistency or back translation in a sequence of prompts. Another option is to generate multiple answers and then use a voting system to pick the best one. This could actually boost the LLM's accuracy, although it would require more computation. In various tasks, there might be simpler methods for verifying the answer than initially generating it.
Then you have techniques like the Tree of Thoughts, which are particularly useful for tasks that require strategic planning and exploration. You just can't solve these in one single round of LLM interaction.
In real-world applications, developers often choose a series of prompts that enable either self-checking or error minimization. Alternatively, they can involve a human in the loop to guide the system's actions. The point is to design with the system's limitations in mind.
On a side note, if you're using vLLM, you can send up to 20 requests in parallel without incurring additional costs. The server batches these requests and uses key-value caching, so you get high token/s throughput. This allows you to resend previous outputs for free or run multiple queries on a large text segment. So, running many tasks doesn't necessarily slow things down if you manage it correctly.
It is a simple problem and in literature it was named "label bias".
Let's say you maximize performance of a single piece of pipeline (training on a dataset or something else), and you do it the same way for all pieces. The labels that were correct as inputs in training are your limitation. Why? Because when a mistake happens, you've never learned to recover from it, because you always gave the correct labels in your training.
What LLM pipelines do is probably something like this:
* a complex task is solved by a pipeline of prompts
* we tweak a single prompt
* we observe the output at the end of the whole pipeline and determine if the tweak was right
In this way, the joint loss of the pipeline is observed and that is ok.
But, the moment your pipeline is: POS Tagger -> Dependency Tree Parser -> Named Entity Recognition -> ... -> Machine Translation
and you have separate training sets that maximize performance of each particular piece, you are introducing label bias and are relying on some luck to recover from errors early in the pipeline because during training, the later parts never got errors as input and recovered to the correct output.
You probably know this but you definitely don't have to run into that problem. In practice most people who use one component to produce features for another will take care to ensure errors are present in the pipeline. So the conceptually simple (but operationally annoying) way to do this is to train your POS tagger or whatever on multiple folds, and predict the missing fold. This is known as "jack-knife training" in the literature.
In spaCy what we do is just train the components in sequence. So everything is trained at the same time, and in the early iterations the model is seeing samples with errors. I've always found this to be good enough.
Yes, I’ve been following spaCy since 2015 and you’ve all been doing great work and made NLP approachable and fast.
Thanks for chiming in.