Add local kernel loading support to KernelConfig().
Author: zheliuyu
Pull request: yes

# What does this PR do?

Add local kernel loading support to transformers.KernelConfig().

Relaed issue: https://github.com/huggingface/transformers/issues/42739

## Before submitting
- [ ] This PR fixes a typo or improves the docs (you can dismiss the other checks if that's the case).
- [x] Did you read the [contributor guideline](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md#create-a-pull-request),
      Pull Request section?
- [x] Was this discussed/approved via a Github issue or the [forum](https://discuss.huggingface.co/)? Please add a link
      to it if that's the case.
- [ ] Did you make sure to update the documentation with your changes? Here are the
      [documentation guidelines](https://github.com/huggingface/transformers/tree/main/docs), and
      [here are tips on formatting docstrings](https://github.com/huggingface/transformers/tree/main/docs#writing-source-documentation).
- [ ] Did you write any new necessary tests?

## Test
```python
import time
import logging
from transformers import AutoModelForCausalLM, AutoTokenizer, KernelConfig


# Set the level to `DEBUG` to see which kernels are being called.
logging.basicConfig(level=logging.DEBUG)

model_name = "/root/Qwen3"

kernel_mapping = {
    "RMSNorm":
        "/root/liger_kernels:liger_kernels:LigerRMSNorm",
}

kernel_config = KernelConfig(kernel_mapping)

# Load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto",
    kernel_config=kernel_config
)

# Prepare the model input
prompt = "Output the first 20 digits of pi."
messages = [{"role": "user", "content": prompt}]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=False,
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

# Warm_up
for _ in range(2):
    generated_ids = model.generate(**model_inputs, max_new_tokens=32768)
    output_ids = generated_ids[0][len(model_inputs.input_ids[0]) :].tolist()

# Print Runtime
for _ in range(5):
    start_time = time.time()
    generated_ids = model.generate(**model_inputs, max_new_tokens=32768)
    print("runtime: ", time.time() - start_time)
    output_ids = generated_ids[0][len(model_inputs.input_ids[0]) :].tolist()
    content = tokenizer.decode(output_ids, skip_special_tokens=True).strip("\n")
    print("content:", content)
```


**Output:**
```
use_kernel_func_from_hub is not available in the installed kernels version. Please upgrade kernels to use this feature.
A kernel_config was provided but use_kernels is False; setting use_kernels=True automatically. To suppress this warning, explicitly set use_kernels to True.
Loading weights: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 311/311 [00:00<00:00, 665.31it/s, Materializing param=model.norm.weight]
The tied weights mapping and config for this model specifies to tie model.embed_tokens.weight to lm_head.weight, but both are present in the checkpoints, so we will NOT tie them. You should update the config with `tie_word_embeddings=False` to silence this warning
INFO:root:Using layer `LigerRMSNorm` from repo `/root/liger_kernels` (package: liger_kernels), layer `LigerRMSNorm`
DEBUG:root:kernelize mode: Mode.INFERENCE, repo mode: Mode.INFERENCE
INFO:root:Using layer `LigerRMSNorm` from repo `/root/liger_kernels` (package: liger_kernels), layer `LigerRMSNorm`
DEBUG:root:kernelize mode: Mode.INFERENCE, repo mode: Mode.INFERENCE
/root/miniconda3/lib/python3.12/site-packages/kernels/layer.py:918: UserWarning: 
No kernel mapping found for layer `SiLU`. Check if the layer name matches one of the kernels in the mapping or add the kernel you want to use to the mapping. Defaulting to original forward implementation.
  warnings.warn(
INFO:root:Using layer `LigerRMSNorm` from repo `/root/liger_kernels` (package: liger_kernels), layer `LigerRMSNorm`
DEBUG:root:kernelize mode: Mode.INFERENCE, repo mode: Mode.INFERENCE

...

INFO:root:Using layer `LigerRMSNorm` from repo `/root/liger_kernels` (package: liger_kernels), layer `LigerRMSNorm`
DEBUG:root:kernelize mode: Mode.INFERENCE, repo mode: Mode.INFERENCE
runtime:  1.0340442657470703
content: The first 20 digits of π (pi) are:

**3.14159265358979323846**.
runtime:  0.9599497318267822
content: The first 20 digits of π are:

**3.14159265358979323846**.

Let me know if you'd like the next 20 digits!
runtime:  0.8574888706207275
content: The first 20 digits of π are:

**3.14159265358979323846**

Let me know if you'd like the next 10 digits or more!
runtime:  0.7771825790405273
content: The first 20 digits of π are:

**3.14159265358979323846**

Let me know if you'd like more digits!
runtime:  0.6569499969482422
content: The first 20 digits of π are:  
**3.14159265358979323846**.
```


Comments:
cc @mekkcyber

Hi @zheliuyu ! Thank you for this nice PR, let me know when it's ready 

After submitting the draft yesterday, some unknown CI errors appeared, but they seem to have been resolved now. So, this PR is ready for review. @MekkCyber @Rocketknight1 

Let me offer some context for the review:
- To avoid complex validation in `from_pretrained()`, no new flag (e.g., use_local_kernels) was added, the existing `use_kernels` flag suffices. The decision to load locally should be handled when parsing the `kernel_mapping` field.
- Specify the input format for locally loading kernels as `RMSNorm":"/abs-path:package_name:layer_name`. This format can leverage the existing string validation logic from `store_registered_layer_names()`.
- Add a `check_kernel_from_local` flag for differentiating remote and local loading.
- Create a new `add_to_mapping_local` to parse the `repo_path`, `package_name`, and `layer_name` fields from `kernel_mapping` for `kernels.LocalLayerRepository`.
- Param `inherit_mapping` should be `False` to avoid still loading kernel from remote when enable `check_kernel_from_local=True`.
- Func `update_kernel()` is currently not in use. Remove it?



Cool! Commenting to add some docs for this once #42277 is merged

@MekkCyber Simplified kernel path.

#### Test passed

```python
kernel_mapping = {
    "RMSNorm":
        "/root/liger_kernels:LigerRMSNorm",
}

kernel_config = KernelConfig(kernel_mapping)

# Load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto",
    kernel_config=kernel_config
)
```

#### Test passed
``` diff
kernel_mapping = {
    "RMSNorm":
        "/root/liger_kernels:LigerRMSNorm",
}

+ kernel_config = KernelConfig(kernel_mapping, use_local_kernel=True)

# Load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto",
    use_kernels=True,
    kernel_config=kernel_config
)
```

The docs for this PR live [here](https://moon-ci-docs.huggingface.co/docs/transformers/pr_42800). All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.