Repository navigation
Support Environment Sensitive Staging #40699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
30f6d8e
73038ac
49877e4
4044735
56034fd
15382fe
4bec8d5
1870a42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "comment": "Modify this file in a trivial way to cause this test suite to run.", | ||
| "pr": "40241", | ||
| "modification": 66 | ||
| "pr": "40699", | ||
| "modification": 68 | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -211,7 +211,18 @@ func launchSDKProcess() error { | |||||
| defer cleanupFunc() | ||||||
| } | ||||||
|
|
||||||
| dir := filepath.Join(*semiPersistDir, "staged") | ||||||
| // Stage under a per-container directory | ||||||
| // So that, SDK containers for different environments sharing the same | ||||||
| // semi-persistent volume cannot overwrite each other's fixed-name | ||||||
| // artifacts (requirements.txt, pickled_main_session, etc.,). | ||||||
| semiPersist := filepath.Join(*semiPersistDir, *id) | ||||||
| dir := filepath.Join(semiPersist, "staged") | ||||||
| // Remove this worker's directory on exit so that it does not accumulate on | ||||||
| // runners that reuse the environment for multiple pipelines. Only a direct | ||||||
| // child of semiPersistDir is ever removed. | ||||||
| if filepath.Dir(semiPersist) == filepath.Clean(*semiPersistDir) { | ||||||
| defer os.RemoveAll(semiPersist) | ||||||
| } | ||||||
| files, err := artifact.Materialize(ctx, *artifactEndpoint, info.GetDependencies(), info.GetRetrievalToken(), dir) | ||||||
| if err != nil { | ||||||
| fmtErr := fmt.Errorf("failed to retrieve staged files: %v", err) | ||||||
|
|
@@ -257,7 +268,9 @@ func launchSDKProcess() error { | |||||
| logger.Fatalf(ctx, "Failed to load pipeline options to worker: %v", err) | ||||||
| } | ||||||
|
|
||||||
| os.Setenv("SEMI_PERSISTENT_DIRECTORY", *semiPersistDir) | ||||||
| // Point the SDK worker at the per-environment root so that it keeps | ||||||
| // resolving <SEMI_PERSISTENT_DIRECTORY>/staged/... (e.g. pickled_main_session). | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My main concern is: some users might have made assumptions where files are staged, now the path becomes dynamic, so we need to evaluate it on the worker and not at pipeline construction. We need to communicate that this is a breaking change for Python in CHANGES.md and guide users how to navigate this change. I think any code that hardcodes /tmp/staged/... (non-dataflow) or smth like /var/opt/google/staged/... will fail to find files in the right location. We can point users to a code snippet https://beam.apache.org/documentation/sdks/python-pipeline-dependencies/#accessing-staged-files-on-the-workers (sent you a PR correcting it slightly). We might need to highlight that this evaluation needs to run on the workers, and not at pipeline submission. We should check how would users use --files_to_stage to supply a model, and then point RunInference transform to the model that was staged? We can start with checking if these tests will fail
Line 49 in eb8f207
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, if some already know that main requirements are replacing the provider and did not supply all the required dependencies for transforms and included then in main requirements to form super set. The pipeline would break with no module error.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, Updated CHANGES.md
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm let me check the tests. I do not think users should know and care about how workers are downloading and managing dependencies. Tests We have written, I agree we can find a way to fix them.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tvalentyn Created #40795 for fixing the tests |
||||||
| os.Setenv("SEMI_PERSISTENT_DIRECTORY", semiPersist) | ||||||
| os.Setenv("LOGGING_API_SERVICE_DESCRIPTOR", (&pipepb.ApiServiceDescriptor{Url: *loggingEndpoint}).String()) | ||||||
| os.Setenv("CONTROL_API_SERVICE_DESCRIPTOR", (&pipepb.ApiServiceDescriptor{Url: *controlEndpoint}).String()) | ||||||
| os.Setenv("RUNNER_CAPABILITIES", strings.Join(info.GetRunnerCapabilities(), " ")) | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm thinking, resolving at runtime becomes non-trivial if the arg must be supplied at pipeline construction time. For example
beam/sdks/python/apache_beam/ml/inference/pytorch_inference.py
Line 201 in b9a783a
if i use --files_to_stage to stage a model, how would is specify a path to that model on the worker correctly? the env var value is not known yet, it must be evaluated at runtime.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having to define a custom MH like in https://github.com/apache/beam/pull/40795/changes is beyond of the recommendation provided here:
for example os.path.join(os.environ['SEMI_PERSISTENT_DIRECTORY'], 'staged', 'my_file'). See [Accessing staged files on the workers]There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think overall we need this change, but I'd argue we don't have a good solution yet for users who might be affected by this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
esp for non-dataflow runners. I guess for dataflow in most cases we need to append some predefined default worker id? like /var/opt/google/staged/sdk-0/ . this is still brittle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, i do not have great answer to pipeline construction path, this might be heavy but customers can follow pattern like github.com//pull/40795 or use to gs:// If you really think there should be a migration path, we can copy the files to both /var/opt/google/staged/.. and /var/opt/google/staged/worker_id/..for a few versions and warn them to migrate. But it adds memory too. I do not know if this path is such a critical usecase.