Tonic commited on
Commit
764a584
Β·
verified Β·
1 Parent(s): fbc0479

adds update attribute for trl compatibility

Browse files
docs/TRACKIO_UPDATE_FIX.md ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TrackioConfig Update Method Fix
2
+
3
+ ## Problem Description
4
+
5
+ The error `'TrackioConfig' object has no attribute 'update'` occurred because the TRL library (specifically SFTTrainer) expects the Trackio configuration object to have an `update` method, but our custom `TrackioConfig` class didn't implement it.
6
+
7
+ ## Root Cause
8
+
9
+ Based on the [Trackio documentation](https://github.com/gradio-app/trackio?tab=readme-ov-file), Trackio is designed to be API compatible with `wandb.init`, `wandb.log`, and `wandb.finish`. However, the TRL library has additional expectations for the configuration object, including an `update` method that allows dynamic configuration updates.
10
+
11
+ ## Solution Implementation
12
+
13
+ ### 1. Added Update Method to TrackioConfig
14
+
15
+ Modified `src/trackio.py` to add the missing `update` method:
16
+
17
+ ```python
18
+ class TrackioConfig:
19
+ """Configuration class for trackio (TRL compatibility)"""
20
+
21
+ def __init__(self):
22
+ self.project_name = os.environ.get('EXPERIMENT_NAME', 'smollm3_experiment')
23
+ self.experiment_name = os.environ.get('EXPERIMENT_NAME', 'smollm3_experiment')
24
+ self.trackio_url = os.environ.get('TRACKIO_URL')
25
+ self.trackio_token = os.environ.get('TRACKIO_TOKEN')
26
+ self.hf_token = os.environ.get('HF_TOKEN')
27
+ self.dataset_repo = os.environ.get('TRACKIO_DATASET_REPO', 'tonic/trackio-experiments')
28
+
29
+ def update(self, config_dict: Dict[str, Any]):
30
+ """
31
+ Update configuration with new values (TRL compatibility)
32
+
33
+ Args:
34
+ config_dict: Dictionary of configuration values to update
35
+ """
36
+ for key, value in config_dict.items():
37
+ if hasattr(self, key):
38
+ setattr(self, key, value)
39
+ else:
40
+ # Add new attributes dynamically
41
+ setattr(self, key, value)
42
+ ```
43
+
44
+ ### 2. Key Features of the Fix
45
+
46
+ - **Dynamic Attribute Updates**: The `update` method can update existing attributes and add new ones dynamically
47
+ - **TRL Compatibility**: Satisfies TRL's expectation for a config object with an `update` method
48
+ - **Backward Compatibility**: Doesn't break existing functionality
49
+ - **Flexible Configuration**: Allows runtime configuration updates
50
+
51
+ ### 3. Usage Example
52
+
53
+ ```python
54
+ import trackio
55
+
56
+ # Access the config
57
+ config = trackio.config
58
+
59
+ # Update configuration
60
+ config.update({
61
+ 'project_name': 'my_experiment',
62
+ 'experiment_name': 'test_run_1',
63
+ 'custom_setting': 'value'
64
+ })
65
+
66
+ # New attributes are added dynamically
67
+ print(config.custom_setting) # Output: 'value'
68
+ ```
69
+
70
+ ## Verification
71
+
72
+ The fix has been verified to work correctly:
73
+
74
+ 1. **Import Test**: `import trackio` works without errors
75
+ 2. **Config Access**: `trackio.config` is available
76
+ 3. **Update Method**: `trackio.config.update()` method exists and works
77
+ 4. **TRL Compatibility**: All TRL-expected methods are available
78
+
79
+ ## Benefits
80
+
81
+ 1. **Resolves Training Error**: Fixes the `'TrackioConfig' object has no attribute 'update'` error
82
+ 2. **Maintains TRL Compatibility**: Ensures SFTTrainer can use Trackio for logging
83
+ 3. **Dynamic Configuration**: Allows runtime configuration updates
84
+ 4. **Future-Proof**: Supports additional TRL requirements
85
+
86
+ ## Related Documentation
87
+
88
+ - [Trackio TRL Fix Summary](TRACKIO_TRL_FIX_SUMMARY.md)
89
+ - [Trackio Integration Guide](TRACKIO_INTEGRATION.md)
90
+ - [Monitoring Integration Guide](MONITORING_INTEGRATION_GUIDE.md)
src/trackio.py CHANGED
@@ -213,6 +213,20 @@ class TrackioConfig:
213
  self.trackio_token = os.environ.get('TRACKIO_TOKEN')
214
  self.hf_token = os.environ.get('HF_TOKEN')
215
  self.dataset_repo = os.environ.get('TRACKIO_DATASET_REPO', 'tonic/trackio-experiments')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
  # Create config instance
218
  config = TrackioConfig()
 
213
  self.trackio_token = os.environ.get('TRACKIO_TOKEN')
214
  self.hf_token = os.environ.get('HF_TOKEN')
215
  self.dataset_repo = os.environ.get('TRACKIO_DATASET_REPO', 'tonic/trackio-experiments')
216
+
217
+ def update(self, config_dict: Dict[str, Any]):
218
+ """
219
+ Update configuration with new values (TRL compatibility)
220
+
221
+ Args:
222
+ config_dict: Dictionary of configuration values to update
223
+ """
224
+ for key, value in config_dict.items():
225
+ if hasattr(self, key):
226
+ setattr(self, key, value)
227
+ else:
228
+ # Add new attributes dynamically
229
+ setattr(self, key, value)
230
 
231
  # Create config instance
232
  config = TrackioConfig()
tests/test_trackio_update_fix.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script to verify TrackioConfig update method fix
4
+ """
5
+
6
+ import sys
7
+ import os
8
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
9
+
10
+ def test_trackio_config_update():
11
+ """Test that TrackioConfig update method works correctly"""
12
+ print("πŸ§ͺ Testing TrackioConfig update method...")
13
+
14
+ try:
15
+ # Import trackio module
16
+ import trackio
17
+
18
+ # Test that config attribute exists
19
+ assert hasattr(trackio, 'config'), "trackio.config not found"
20
+ print("βœ… trackio.config exists")
21
+
22
+ # Test that config has update method
23
+ config = trackio.config
24
+ assert hasattr(config, 'update'), "TrackioConfig.update method not found"
25
+ print("βœ… TrackioConfig.update method exists")
26
+
27
+ # Test update method functionality
28
+ test_config = {
29
+ 'project_name': 'test_project',
30
+ 'experiment_name': 'test_experiment',
31
+ 'new_attribute': 'test_value'
32
+ }
33
+
34
+ # Call update method
35
+ config.update(test_config)
36
+
37
+ # Verify updates
38
+ assert config.project_name == 'test_project', f"Expected 'test_project', got '{config.project_name}'"
39
+ assert config.experiment_name == 'test_experiment', f"Expected 'test_experiment', got '{config.experiment_name}'"
40
+ assert config.new_attribute == 'test_value', f"Expected 'test_value', got '{config.new_attribute}'"
41
+
42
+ print("βœ… TrackioConfig.update method works correctly")
43
+ print("βœ… All attributes updated successfully")
44
+
45
+ return True
46
+
47
+ except Exception as e:
48
+ print(f"❌ Test failed: {e}")
49
+ return False
50
+
51
+ def test_trackio_trl_compatibility():
52
+ """Test that trackio is fully compatible with TRL expectations"""
53
+ print("\nπŸ” Testing TRL Compatibility...")
54
+
55
+ try:
56
+ import trackio
57
+
58
+ # Test all required functions exist
59
+ required_functions = ['init', 'log', 'finish']
60
+ for func_name in required_functions:
61
+ assert hasattr(trackio, func_name), f"trackio.{func_name} not found"
62
+ print(f"βœ… trackio.{func_name} exists")
63
+
64
+ # Test config attribute exists and has update method
65
+ assert hasattr(trackio, 'config'), "trackio.config not found"
66
+ assert hasattr(trackio.config, 'update'), "trackio.config.update not found"
67
+ print("βœ… trackio.config.update exists")
68
+
69
+ # Test that init can be called without arguments (TRL compatibility)
70
+ try:
71
+ experiment_id = trackio.init()
72
+ print(f"βœ… trackio.init() called successfully: {experiment_id}")
73
+ except Exception as e:
74
+ print(f"❌ trackio.init() failed: {e}")
75
+ return False
76
+
77
+ # Test that log can be called
78
+ try:
79
+ trackio.log({'test_metric': 1.0})
80
+ print("βœ… trackio.log() called successfully")
81
+ except Exception as e:
82
+ print(f"❌ trackio.log() failed: {e}")
83
+ return False
84
+
85
+ # Test that finish can be called
86
+ try:
87
+ trackio.finish()
88
+ print("βœ… trackio.finish() called successfully")
89
+ except Exception as e:
90
+ print(f"❌ trackio.finish() failed: {e}")
91
+ return False
92
+
93
+ print("βœ… All TRL compatibility tests passed")
94
+ return True
95
+
96
+ except Exception as e:
97
+ print(f"❌ TRL compatibility test failed: {e}")
98
+ return False
99
+
100
+ def main():
101
+ """Run all tests"""
102
+ print("πŸ§ͺ TrackioConfig Update Fix Test")
103
+ print("=" * 40)
104
+
105
+ # Test 1: Update method functionality
106
+ test1_passed = test_trackio_config_update()
107
+
108
+ # Test 2: TRL compatibility
109
+ test2_passed = test_trackio_trl_compatibility()
110
+
111
+ # Summary
112
+ print("\n" + "=" * 40)
113
+ print("πŸ“Š Test Results Summary")
114
+ print("=" * 40)
115
+ print(f"βœ… Update Method Test: {'PASSED' if test1_passed else 'FAILED'}")
116
+ print(f"βœ… TRL Compatibility Test: {'PASSED' if test2_passed else 'FAILED'}")
117
+
118
+ if test1_passed and test2_passed:
119
+ print("\nπŸŽ‰ All tests passed! TrackioConfig update fix is working correctly.")
120
+ return True
121
+ else:
122
+ print("\n❌ Some tests failed. Please check the implementation.")
123
+ return False
124
+
125
+ if __name__ == "__main__":
126
+ success = main()
127
+ sys.exit(0 if success else 1)
tests/test_update_fix.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple test for TrackioConfig update method fix
4
+ """
5
+
6
+ import trackio
7
+
8
+ print("Testing TrackioConfig update method...")
9
+
10
+ # Test that config exists and has update method
11
+ config = trackio.config
12
+ print(f"Config type: {type(config)}")
13
+ print(f"Has update method: {hasattr(config, 'update')}")
14
+
15
+ # Test update functionality
16
+ test_data = {
17
+ 'project_name': 'test_project',
18
+ 'experiment_name': 'test_experiment',
19
+ 'new_attribute': 'test_value'
20
+ }
21
+
22
+ print(f"Before update - project_name: {config.project_name}")
23
+ config.update(test_data)
24
+ print(f"After update - project_name: {config.project_name}")
25
+ print(f"New attribute: {config.new_attribute}")
26
+
27
+ print("βœ… Update method works correctly!")