Regression testing for Flax examples - #144
Conversation
389e359 to
6c43baf
Compare
MostafaDehghani
left a comment
There was a problem hiding this comment.
Thank Alexey!
The proposal is pretty nice and the Benchmark class is brilliant.
I have one question though. Is this supposed to support training all examples to the convergence and assert the final performance?
|
Thanks for the review, Mostafa! The class support training full example for just a few epochs or running full training. The attached benchmarks for imagenet and cifar10 are "toy" benchmarks. They run much faster than what complete training would take and the idea is to use them while we figure out the intergration with the systems that will consume benchmark reports (JSON files produced for each tests). Once that's running smooth, we can switch to complete training - this should be just a matter of updating 3 lines or so for each of the examples. |
avital
left a comment
There was a problem hiding this comment.
This looks good! I made a few suggestion.
mohitreddy1996
left a comment
There was a problem hiding this comment.
Few nits, rest LGTM :)
Prototype regression testing / benchmark framework for Flax examples
This provides an API/framework for users to write regression tests for their examples. Two goals were kept in mind when designing this:
Using TensorBoard logs to extract regression metrics
Most examples already log the metrics of interest (e.g. time per epoch, training accuracy, perplexity, etc) to TensorBoard (TB) during training. These logs thus contain all the information required for detecting a regression. Extracting this information from the TB logs thus immediately makes most examples ready for regression testing without any modifications.
This holds true for all but the simplest examples (e.g. MNIST) that do not rely on TB. For these examples we can either add TB logging (recommended solution), or do something weird like capturing
stderroutput and parsing it. The latter is cumbersome, but allows for keeping the simplest examples simple.Currently, the framework only includes a thin wrapper for reading TB scaler summaries.
API
The user API was kept minimal and similar to what unit tests would use. Specifically, it supports the following
Reporting
We also allow reporting "extras" - any additional textual information. Currently this is used for adding information about failed assertions and test descriptions.
Reporting is done via the
report_metric('name', value)andreport_metrics({'name': value})methods for the metrics; andreport_extra('name', 'value')andreport_extras({'name': 'value'})methods for the extras. There is also a separatereport_wall_time(value)method consumed by the CI framework we plant to interface with (more on that later).Asserting
We allow using the full spectrum of the
unittest/absltestself.assert*methods for verifying benchmark metrics / correctness. This achieves two goals. First, this provides the familiar unit testing API to the end users; and second, this makes reporting metrics and checking their values completely independent, thus allowing for simple APIs for both.The cost of this simplicity is that we need to override the default behaviour of
self.assert*methods. Whereas normally a failed assertion would immediately cause the test to halt, we now detect failures as before, but defer raising them until the end of the test. This guarantees that the benchmark always produces output/report, even if the metric values were outside of the permitted value ranges. Furthermore, overriding assertion methods allows for automatically detecting and reporting benchmark failures.Example benchmark
Together, this allows for concise benchmark code. See example below for CIFAR10.
Interfacing with monitoring / CI frameworks
The current plan is to interface with an external monitoring / CI framework by exporting benchmark results as a simple JSON file with the following format
The support for this is implemented behind the scenes. So long as end uses use the
self.report_*methods in their benchmark code, the framework will take care of aggregating the metrics, extras, figuring out the name of the test and the file, etc. As a bonus, if any of the assertions fail, the framework will output their error messages underextras.JSON files (one per test method) should automatically written to disk after each test if the
benchmark_output_diris specified as an absl flag. I haven't actually tested that this works since I couldn't figure out how to get the pytest running to set flags.What's included in this PR?
This PR implements the framework described above, and adds (for now) toy benchmarks for ImageNet (2 epochs on 8xV100), CIFAR10 (2 epochs on 1xV100) and MNIST (full training on CPU). The MNIST example was also modified to produce TB summaries.
this