Repository: pytorch
Issue: How to use torch.compile + HF model?
Labels: triaged,oncall: pt2,module: dynamo

### 🐛 Describe the bug

Problem: There seem to be 2 ways of using torch compile with a HF model, both of which don't work for all the ways a model inference is called, which is one of 3 possible methods: `generate()`, `forward()` and `__call__()`.

## Option 1: `model = torch.compile(model)`

This works if we use either `forward()` or the `__call__()` methods. But, if we try to call the `.generate()` method (which is the more popular API for inferencing and calls `forward()` internally), we notice that we DON'T seem to be using the compiled model (ex. `TORCH_LOGS="dynamo"` gives no output).

Simple reproducible example (custom class with `generate` and `forward` like implementations):
```
import torch

class MyModule(torch.nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input):
        # return average of the inputs
        return torch.Tensor(torch.sum(input)/len(input))

    def generate(self, max_tokens, input):
        for i in range(max_tokens):
            output = self(input) # Doesn't work with either call or forward
            input = torch.cat((input, output.view(1)))
        return input

model = MyModule()
model = torch.compile(model)
input = torch.rand(4)
output = model.generate(input=input, max_tokens=3) # THIS DOES NOT WORK!!!
#output = model.forward(input=input) # THIS WORKS
``` 

or use any HF model compile followed by generate:
```
model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
model = torch.compile(model)
output = model.generate(input_ids, max_new_tokens=100)
```

The problem is that the output of `torch.compile(model)` is an `OptimizedModule` object with the `__call__()` set to the compiled forward and `orig_mod` set to `model` itself. 
When `compiled_model.generate()` is called, this accesses the generate through the `__getattr__()` function which gets the model's generate. That `generate` calls `self()`, which calls the original model's forward instead of the compiled forward.

## Option 2: `model.compile()`
The other option is to use the `torch.nn.Module`'s compile, which does an inplace modification where the compiled forward is stored in `_compiled_call_impl` variable and used when `__call__()` is done. But, this only works with the `__call__()` method and does NOT work with the `forward()` method. If the `generate()` internally uses call, then generate works.

```
model.compile()
output = model.generate(input=input, max_tokens=3) # Works
#output = model.forward(input_ids) # DOES NOT WORK
```

Problem is that neither of these approaches works with both `generate()` and `forward()` methods. 

As an aside, I tried a couple of unsuccessful possible fixes:
- Tried if Option 1 could be fixed somehow by setting the `orig_mod.forward` to the compiled forward but that causes infinite recursion because of the circular dependency
- I also tried changing  `TorchDynamoContext.__call__()` (in `eval_frame.py`) in the nn.Module case, to internally do `model.compile` instead of creating an OptimizedModule. This fixes things slightly, for ex. Option 1 works if it generate uses `call` instead of `forward`, but obviously, not really a solution.

cc: @chanderg

### Error logs

_No response_

### Versions

Collecting environment information...
PyTorch version: 2.6.0.dev20241103+cu124
Is debug build: False
CUDA used to build PyTorch: 12.4
ROCM used to build PyTorch: N/A

OS: Ubuntu 22.04.4 LTS (x86_64)
GCC version: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Clang version: Could not collect
CMake version: version 3.30.2
Libc version: glibc-2.35

Python version: 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0] (64-bit runtime)
Python platform: Linux-5.14.0-284.73.1.el9_2.x86_64-x86_64-with-glibc2.35
Is CUDA available: True
CUDA runtime version: 12.6.68
CUDA_MODULE_LOADING set to: LAZY
GPU models and configuration: 
GPU 0: NVIDIA A100-SXM4-80GB
GPU 1: NVIDIA A100-SXM4-80GB
GPU 2: NVIDIA A100-SXM4-80GB
GPU 3: NVIDIA A100-SXM4-80GB
GPU 4: NVIDIA A100-SXM4-80GB
GPU 5: NVIDIA A100-SXM4-80GB
GPU 6: NVIDIA A100-SXM4-80GB
GPU 7: NVIDIA A100-SXM4-80GB

Nvidia driver version: 525.105.17
cuDNN version: Probably one of the following:
/usr/lib/x86_64-linux-gnu/libcudnn.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_adv.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_cnn.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_engines_precompiled.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_engines_runtime_compiled.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_graph.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_heuristic.so.9.4.0
/usr/lib/x86_64-linux-gnu/libcudnn_ops.so.9.4.0
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

CPU:
Architecture:                       x86_64
CPU op-mode(s):                     32-bit, 64-bit
Address sizes:                      48 bits physical, 48 bits virtual
Byte Order:                         Little Endian
CPU(s):                             256
On-line CPU(s) list:                0-255
Vendor ID:                          AuthenticAMD
Model name:                         AMD EPYC 7763 64-Core Processor
CPU family:                         25
Model:                              1
Thread(s) per core:                 2
Core(s) per socket:                 64
Socket(s):                          2
Stepping:                           1
Frequency boost:                    enabled
CPU max MHz:                        3529.0520
CPU min MHz:                        1500.0000
BogoMIPS:                           4900.23
Flags:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 invpcid_single hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd amd_ppin brs arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca
Virtualization:                     AMD-V
L1d cache:                          4 MiB (128 instances)
L1i cache:                          4 MiB (128 instances)
L2 cache:                           64 MiB (128 instances)
L3 cache:                           512 MiB (16 instances)
NUMA node(s):                       2
NUMA node0 CPU(s):                  0-63,128-191
NUMA node1 CPU(s):                  64-127,192-255
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Not affected
Vulnerability Spec rstack overflow: Mitigation; Safe RET
Vulnerability Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:           Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:           Mitigation; Retpolines, IBPB conditional, IBRS_FW, STIBP always-on, RSB filling, PBRSB-eIBRS Not affected
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected

Versions of relevant libraries:
[pip3] mypy-extensions==1.0.0
[pip3] numpy==1.24.4
[pip3] nvidia-cublas-cu12==12.4.5.8
[pip3] nvidia-cuda-cupti-cu12==12.4.127
[pip3] nvidia-cuda-nvrtc-cu12==12.4.127
[pip3] nvidia-cuda-runtime-cu12==12.4.127
[pip3] nvidia-cudnn-cu12==9.1.0.70
[pip3] nvidia-cudnn-frontend==1.6.0
[pip3] nvidia-cufft-cu12==11.2.1.3
[pip3] nvidia-curand-cu12==10.3.5.147
[pip3] nvidia-cusolver-cu12==11.6.1.9
[pip3] nvidia-cusparse-cu12==12.3.1.170
[pip3] nvidia-cusparselt-cu12==0.6.2
[pip3] nvidia-nccl-cu12==2.21.5
[pip3] nvidia-nvjitlink-cu12==12.4.127
[pip3] nvidia-nvtx-cu12==12.4.127
[pip3] nvtx==0.2.5
[pip3] onnx==1.16.2
[pip3] optree==0.12.1
[pip3] pynvjitlink==0.3.0
[pip3] pytorch-triton==3.1.0+cf34004b8a
[pip3] torch==2.6.0.dev20241103+cu124
[pip3] torch_tensorrt==2.5.0a0
[pip3] torchaudio==2.5.0.dev20241103+cu124
[pip3] torchdata==0.9.0
[pip3] torchvision==0.20.0.dev20241103+cu124

cc @chauhang @penguinwu @voznesenskym @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @chenyang78 @kadeng @amjames