I believe kapt is basically a port of the Java annotation processor that knows about kotlin source. It’s slow, because it runs outside the compiler as a separate process that reads source code and usually outputs source code that then needs to be compiled itself.
KSP is a compiler plugin that processes IR code directly. It is designed to serve similar use cases as kapt, but because it’s a compiler plugin and not a separate process, it is much lower overhead to run and can integrate more tightly with kotlin features.
The kotlin compiler has always supported plugins, but until recently the api was a bit limited, and plugins had to be written specifically for one of the backends: jvm, js, or native. The new IR backend introduces a special bytecode, Intermediate Representation, that compiler plugins can read and write, that is independent of jvm/js/native. The compiler plugin api is also much more flexible and powerful. IR plugins can be written once and automatically support all of jvm, js, native, and any future targets.