Comments (13)
After some offline discussion, we have settled on the following code:
class HfRunner:
def __init__(self, ...):
self.model = create_model(...)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
del self.model
cleanup()
Although HfRunner
can only be used once as a context manager, it is sufficient for testing. This passes the type checker without needlessly complicating the existing code.
from vllm.
Love this!
from vllm.
Actually the destructor of hf_runner should call cleanup() which calls gc.collect()
Line 359 in 388596c
Is this not sufficient?
from vllm.
Actually the destructor of hf_runner should call cleanup() which calls gc.collect()
Line 359 in 388596c
Is this not sufficient?
__del__
is only called when the object is actually GC'ed, not when the del
statement is used.
In any case, I think the context manager approach is cleaner. However, this will require refactoring the runner classes to only initialize the model when the context manager is entered.
from vllm.
Btw in general, we should prefer weakref.finalize
over __del__
. See this documentation for more details.
from vllm.
@rkooo567 I updated the code and the output. __del__
is not enough here. You can see that A.__del__
calls del self.tensor
. However, the tensor is destructed before A.__del__
is called. That's why Python gc is not reliable, especially when we need to enforce some destruction order.
from vllm.
In any case, I think the context manager approach is cleaner. However, this will require refactoring the runner classes to only initialize the model when the context manager is entered.
@DarkLight1337 not necessary. We can make the runner itself a context manager. e.g. adding the following lines:
class HfRunner:
...
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
del self
cleanup()
Then the following change should be enough:
- hf_model = hf_runner(model, dtype=dtype)
- hf_outputs = hf_model.generate_greedy(example_prompts, max_tokens)
- del hf_model
+ with hf_runner(model, dtype=dtype) as hf_model:
+ hf_outputs = hf_model.generate_greedy(example_prompts, max_tokens)
We should avoid using weakref.finalize
or __del__
. They are just not reliable.
from vllm.
class HfRunner: ... def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): del self cleanup()
I don't think this will work. In particular, del self
does not really do anything since the HfRunner
is still inside the scope of the test function. We should instead operate on the wrapped model (self.model
) directly.
from vllm.
We should avoid using
weakref.finalize
or__del__
. They are just not reliable.
Yeah, they are both dependant on GC so they aren't suitable in situations where GC is not even being invoked.
from vllm.
I don't think this will work. In particular,
del self
does not really do anything since theHfRunner
is still inside the scope of the test function. We should instead operate on the wrapped model (self.model
) directly.
Good point. How about del self.model
inside __exit__
?
from vllm.
I don't think this will work. In particular,
del self
does not really do anything since theHfRunner
is still inside the scope of the test function. We should instead operate on the wrapped model (self.model
) directly.
This is what I mean:
class HfRunner:
def __init__(self, ...):
- self.model = create_model(...)
+ self.model = None
def __enter__(self):
+ self.model = create_model(...)
return self
def __exit__(self, exc_type, exc_value, traceback):
- del self
+ self.model = None
cleanup()
There is no need to del self.model
explicitly. Setting self.model = None
should be sufficient to remove the reference to the HuggingFace model (or LLM
object for VllmRunner
).
from vllm.
I think they are equivalent. For the following code:
with hf_runner(model, dtype=dtype) as hf_model:
hf_outputs = hf_model.generate_greedy(example_prompts, max_tokens)
The function call chain is:
hf_model = hf_runner() # essentially HfRunner. __init__
hf_model.__enter__()
hf_outputs = hf_model.generate_greedy(example_prompts, max_tokens)
hf_model. __exit__()
from vllm.
To avoid having to check self.model is not None
each time in the other methods, it may be better to have a separate context manager function that returns the runner object. For example:
@contextlib.contextmanager
def hf_model_runner(*args, **kwargs):
model = create_model(...)
yield HfRunner(model, ...)
del model
cleanup()
class HfRunner:
def __init__(self, model, ...):
self.model = model
# The rest is the same as original HfRunner without context manager. Also we can now remove `__del__` method
from vllm.
Related Issues (20)
- [Bug]: RuntimeError: CUDA error: no kernel image is available for execution on the device CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.
- [Speculative decoding]: The content generated by speculative decoding is inconsistent with the content generated by the target model HOT 3
- [Performance]: Is kv cache implemented globally in vllm, It can be shared by multiple concurrent inferences? HOT 2
- [Feature]: Make a unstable latest docker image HOT 1
- [Performance]: gptq and awq quantization do not improve the performance HOT 4
- [Installation]: Compiling VLLM for cpu only. HOT 2
- [New Model]: mistralai/Codestral-22B-v0.1 HOT 7
- [Usage]: Streaming Response from vLLM 0.4.2 -> 0.4.3 HOT 2
- [Usage]: Function calling for mistral v0.3
- [Bug]: vLLM does not support virtual GPU
- [Bug]: Unexpected prompt token logprob behaviors of llama 2 when setting echo=True for openai-api server HOT 1
- [Bug]: Getting an empty string ('') for every call on fine-tuned Code-Llama-7b-hf model HOT 1
- [Usage]: Howto quiet the terminal 'Info' outputs in vllm HOT 1
- [Performance]: [Automatic Prefix Caching] When hitting the KV cached blocks, the first execute is slow, and then is fast. HOT 3
- [Speculative decoding]: `AttributeError: 'NoneType' object has no attribute 'numel'` when exceeding draft context length HOT 3
- [Bug]: Qwen2 MoE: AttributeError: 'MergedColumnParallelLinear' object has no attribute 'weight'. Did you mean: 'qweight'? HOT 3
- [Bug]: with `--enable-prefix-caching` , `/completions` crashes server with `echo=True` above certain prompt length HOT 2
- [RFC]: Refactor MoE
- [Bug]: TorchSDPAMetadata is out of date HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vllm.